func Pinger(address *net.IPAddr, timeout time.Duration) error { var ( c *net.IPConn err error ) v6 := address.IP.To4() == nil if v6 { c, err = net.DialIP("ip6:ipv6-icmp", nil, address) } else { c, err = net.DialIP("ip4:icmp", nil, address) } if err != nil { return err } c.SetDeadline(time.Now().Add(timeout)) defer c.Close() typ := icmpv4EchoRequest if v6 { typ = icmpv6EchoRequest } xid, xseq := os.Getpid()&0xffff, 1 wb, err := (&icmpMessage{ Type: typ, Code: 0, Body: &icmpEcho{ ID: xid, Seq: xseq, Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3), }, }).Marshal() if err != nil { return err } if _, err = c.Write(wb); err != nil { return err } var m *icmpMessage rb := make([]byte, 20+len(wb)) for { if _, err = c.Read(rb); err != nil { return err } if !v6 { rb = ipv4Payload(rb) } if m, err = parseICMPMessage(rb); err != nil { return err } switch m.Type { case icmpv4EchoRequest, icmpv6EchoRequest: continue } break } return nil }
func singleping(ip string) (time.Duration, error) { addr := net.IPAddr{IP: net.ParseIP(ip)} sendid := os.Getpid() & 0xffff sendseq := 1 pingpktlen := 64 sendpkt := makePingRequest(sendid, sendseq, pingpktlen, []byte("Go Ping")) ipconn, err := net.DialIP("ip4:icmp", nil, &addr) // *IPConn (Conn 인터페이스 구현) if err != nil { log.Fatalf(`net.DialIP("ip4:icmp", %v) = %v`, ipconn, err) } ipconn.SetDeadline(time.Now().Add(time.Second)) //1 Second timeout start := time.Now() n, err := ipconn.WriteToIP(sendpkt, &addr) if err != nil || n != pingpktlen { log.Fatalf(`net.WriteToIP(..., %v) = %v, %v`, addr, n, err) } resp := make([]byte, 1024) _, _, pingerr := ipconn.ReadFrom(resp) if pingerr != nil { fmt.Printf("%s : FAIL\n", ip) } else { fmt.Printf("%s : %s\n", ip, time.Since(start)) } // log.Printf("%x", resp) return time.Since(start), pingerr }
func sendIPPacket() { fmt.Println("go!") ipaddr, err := net.ResolveIPAddr("ip", "192.168.1.254") if err != nil { fmt.Println("IP address is wrong!") return } localAddrs, err := net.InterfaceAddrs() if err != nil { fmt.Println("Local interface is null!") return } lIPAddrs := getSendLocalIP(localAddrs, ipaddr) if lIPAddrs == nil { fmt.Println("Local interface is null!") return } fmt.Println(lIPAddrs.String()) ipConn, err := net.DialIP("ip", &net.IPAddr{IP: lIPAddrs.IP, Zone: ""}, ipaddr) if err != nil { fmt.Println(err.Error()) return } b := []byte{0xAA, 0xBB, 0xCC} _, err = ipConn.Write(b) if err != nil { fmt.Println(err.Error()) return } defer ipConn.Close() }
func main() { var ( icmp ICMP laddr net.IPAddr = net.IPAddr{IP: net.ParseIP("192.168.34.125")} raddr net.IPAddr = net.IPAddr{IP: net.ParseIP("114.114.114.114")} ) conn, err := net.DialIP("ip4:icmp", &laddr, &raddr) if err != nil { fmt.Println(err.Error()) return } defer conn.Close() icmp.Type = 8 //8->echo message 0->reply message icmp.Code = 0 icmp.Checksum = 0 icmp.Identifier = 0 icmp.SequenceNum = 0 var ( buffer bytes.Buffer ) binary.Write(&buffer, binary.BigEndian, icmp) icmp.Checksum = CheckSum(buffer.Bytes()) buffer.Reset() binary.Write(&buffer, binary.BigEndian, icmp) if _, err := conn.Write(buffer.Bytes()); err != nil { fmt.Println(err.Error()) return } fmt.Printf("send icmp packet success!") }
// Ping public method func Ping(ip string) (bool, error) { recv := make([]byte, 1024) //保存响应数据 raddr, err := net.ResolveIPAddr("ip", ip) //raddr为目标主机的地址 if err != nil { fmt.Spintf("resolve ip: %s fail:", ip) return false, err } laddr := net.IPAddr{IP: net.ParseIP("0.0.0.0")} //源地址 if ip == "" { return false, errors.New("ip or domain is null") } conn, err := net.DialIP("ip4:icmp", &laddr, raddr) if err != nil { glog.Errorf("dial ip: %s fail:%v", laddr, err) return false, err } defer conn.Close() buffer := assemblyIcmp() if _, err := conn.Write(buffer.Bytes()); err != nil { fmt.Spintf("post Icmp fail: %v", err) return false, err } conn.SetReadDeadline((time.Now().Add(time.Second * 5))) _, err = conn.Read(recv) if err != nil { fmt.Spintf("get Icmp fail: %v", err) return false, nil } return true, nil }
func ping(host string, timeLimit int) (re PingReturn) { re.success = false re.host = host PingLogger.Println("Ping ", host) raddr, err := net.ResolveIPAddr("ip", host) if err != nil { PingLogger.Println("resolve ip addr error", err) re.msg = "ip error" re.err = err return } else { PingLogger.Println("IP:", raddr) } conn, err := net.DialIP("ip4:icmp", nil, raddr) if err != nil { if strings.Index(err.Error(), "operation not permitted") != -1 { log.Fatalln("operation not permitted, please run it by sudo") } fmt.Printf("%+v\n", err.Error()) PingLogger.Println(err) re.msg = "dial error" re.err = err return } var icmp ICMP icmp.Type = 8 icmp.Code = 0 icmp.Checksum = 0 icmp.Identifier = 0 icmp.SequenceNum = 0 var buffer bytes.Buffer binary.Write(&buffer, binary.BigEndian, icmp) icmp.Checksum = CheckSum(buffer.Bytes()) buffer.Reset() binary.Write(&buffer, binary.BigEndian, icmp) PingLogger.Println("Runing Ping data ", printByte(buffer.Bytes())) conn.Write(buffer.Bytes()) t_start := time.Now() conn.SetReadDeadline((time.Now().Add( time.Duration(timeLimit) * time.Millisecond))) recv := make([]byte, 100) recv_len, err := conn.Read(recv) if err != nil { re.msg = "read error" re.err = err PingLogger.Println(err) return } PingLogger.Println("Recv data ", printByte(recv[:recv_len])) t_end := time.Now() dur := t_end.Sub(t_start).Nanoseconds() / 1e6 PingLogger.Println("Time spend ms", dur) PingLogger.Println("") re.success = true defer conn.Close() return }
func main() { flag.Parse() if ipAddr == "(none)" || ipProto == -1 { log.Panic("usage") } ra, err := net.ResolveIPAddr("ip4", ipAddr) if err != nil { log.Panic(err) } proto := fmt.Sprintf("ip:%d", ipProto) conn, err := net.DialIP(proto, nil, ra) if err != nil { log.Panic(err) } defer conn.Close() in := bufio.NewReader(os.Stdin) line, err := in.ReadSlice('\n') for err == nil { _, err = conn.Write([]byte(line)) if err != nil { log.Panic(err) } line, err = in.ReadSlice('\n') } }
func (sender *udpSenderDF) dial() error { if sender.socket != nil { if err := sender.socket.Close(); err != nil { return err } sender.socket = nil } laddr := &net.IPAddr{IP: sender.localIP} raddr := &net.IPAddr{IP: sender.remoteIP} s, err := net.DialIP("ip4:UDP", laddr, raddr) f, err := s.File() if err != nil { return err } defer f.Close() // This makes sure all packets we send out have DF set on them. err = syscall.SetsockoptInt(int(f.Fd()), syscall.IPPROTO_IP, syscall.IP_MTU_DISCOVER, syscall.IP_PMTUDISC_DO) if err != nil { return err } sender.socket = s return nil }
func dialIP(conn *LocalConnection) (*net.IPConn, error) { ipLocalAddr, err := ipAddr(conn.TCPConn.LocalAddr()) if err != nil { return nil, err } ipRemoteAddr, err := ipAddr(conn.TCPConn.RemoteAddr()) if err != nil { return nil, err } ipSocket, err := net.DialIP("ip4:UDP", ipLocalAddr, ipRemoteAddr) if err != nil { return nil, err } f, err := ipSocket.File() if err != nil { return nil, err } defer f.Close() fd := int(f.Fd()) // This Makes sure all packets we send out have DF set on them. err = syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MTU_DISCOVER, syscall.IP_PMTUDISC_DO) if err != nil { return nil, err } return ipSocket, nil }
func main() { flag.Parse() dst := flag.Arg(0) //dst := "121.254.177.105" raddr, err := net.ResolveIPAddr("ip4", dst) // *IPAddr if err != nil { log.Fatalf(`net.ResolveIPAddr("ip4", %v") = %v, %v`, dst, raddr, err) } ipconn, err := net.DialIP("ip4:icmp", nil, raddr) // *IPConn (Conn 인터페이스 구현) if err != nil { log.Fatalf(`net.DialIP("ip4:icmp", %v) = %v`, ipconn, err) } sendid := os.Getpid() & 0xffff sendseq := 1 pingpktlen := 64 for { sendpkt := makePingRequest(sendid, sendseq, pingpktlen, []byte("Go Ping")) //fmt.Printf("%v, %v\n", sendpkt[0:8], string(sendpkt[8:])) start := time.Now().UnixNano() n, err := ipconn.WriteToIP(sendpkt, raddr) if err != nil || n != pingpktlen { log.Fatalf(`net.WriteToIP(..., %v) = %v, %v`, raddr, n, err) } //ipconn.SetTimeout(5e8) // 0.5 second resp := make([]byte, 1024) for { n, from, err := ipconn.ReadFrom(resp) fmt.Printf("%d bytes from %s: icmp_req=%d time=%.2f ms\n", n, dst, sendseq, elapsedTime(start)) // log.Printf("%x", resp) if err != nil { log.Fatalf(`ReadFrom(...) = %v, %v, %v`, n, from, err) } if resp[0] != ICMP_ECHO_REPLY { continue } rcvid, rcvseq := parsePingReply(resp) if rcvid != sendid || rcvseq != sendseq { log.Fatalf(`Ping reply saw id,seq=0x%x,0x%x (expected 0x%x, 0x%x)`, rcvid, rcvseq, sendid, sendseq) } break } sendseq++ time.Sleep(1e9) // 1 second. like -i (interval) option } }
func send(s string) { log.Printf("sending to %s: %s", addr.String(), s) conn, err := net.DialIP(groupIPProto, nil, addr) if err != nil { log.Panic(err) } defer conn.Close() n, err := conn.Write([]byte(s)) if err != nil { log.Panic(err) } log.Printf("sent %d bytes", n) }
func main() { if len(os.Args) != 2 { fmt.Fprintf(os.Stderr, "Usage: %s host", os.Args[0]) os.Exit(1) } dst := os.Args[1] raddr, err := net.ResolveIPAddr("ip4", dst) checkError(err) ipconn, err := net.DialIP("ip4:icmp", nil, raddr) checkError(err) sendid := os.Getpid() & 0xffff sendseq := 1 pingpktlen := 64 for { sendpkt := makePingRequest(sendid, sendseq, pingpktlen, []byte("")) start := int64(time.Now().Nanosecond()) _, err := ipconn.WriteToIP(sendpkt, raddr) checkError(err) resp := make([]byte, 1024) for { n, from, err := ipconn.ReadFrom(resp) checkError(err) fmt.Printf("%d bytes from %s: icmp_req = %d time = %.2f ms\n", n, from, sendseq, elapsedTime(start)) if resp[0] != ICMP_ECHO_REPLY { continue } rcvid, rcvseq := parsePingReply(resp) if rcvid != sendid || rcvseq != sendseq { fmt.Println("Ping reply saw id ", rcvid, rcvseq, sendid, sendseq) } break } if sendseq == 4 { break } else { sendseq++ } time.Sleep(1e9) } }
func main() { if len(os.Args) != 2 { fmt.Printf("Usage: %s hostname\n", os.Args[0]) os.Exit(1) } addr, err := net.ResolveIPAddr("ip", os.Args[1]) if err != nil { fmt.Printf("Resolution error: %s\n", err.Error()) os.Exit(1) } conn, err := net.DialIP("ip4:icmp", addr, addr) checkError(err) var msg [512]byte msg[0] = 8 // echo msg[1] = 0 // code 0 msg[2] = 0 // checksum, fix later msg[3] = 0 // checksum, fix later msg[4] = 0 // identifier[0] msg[5] = 13 // identifier[1] msg[6] = 0 // sequence[0] msg[7] = 37 // sequence[1] len := 8 check := checkSum(msg[0:len]) msg[2] = byte(check >> 8) msg[3] = byte(check & 255) _, err = conn.Write(msg[0:len]) checkError(err) _, err = conn.Read(msg[0:]) checkError(err) fmt.Println("Got response") if msg[5] == 13 { fmt.Println("Identifier matches") } if msg[7] == 37 { fmt.Println("Sequence matches") } os.Exit(0) }
func TestPing(t *testing.T) { fmt.Println("flag args: ", flag.Args()) if address == "" { t.Error("address is empty") os.Exit(1) } fmt.Println("address is ", address) addr, err := net.ResolveIPAddr("ip", address) if err != nil { fmt.Println("Resolution error", err.Error()) os.Exit(1) } conn, err := net.DialIP("ip4:icmp", addr, addr) checkError(err) var msg [512]byte msg[0] = 8 // echo msg[1] = 0 // code 0 msg[2] = 0 // checksum, fix later msg[3] = 0 // checksum, fix later msg[4] = 0 // identifier[0] msg[5] = 13 //identifier[1] msg[6] = 0 // sequence[0] msg[7] = 37 // sequence[1] len := 8 check := checkSum(msg[0:len]) msg[2] = byte(check >> 8) msg[3] = byte(check & 255) _, err = conn.Write(msg[0:len]) checkError(err) _, err = conn.Read(msg[0:]) checkError(err) fmt.Println("Got response") if msg[5] == 13 { fmt.Println("identifier matches") } if msg[7] == 37 { fmt.Println("Sequence matches") } os.Exit(0) }
func dialAddr(net, addr string, addri netpkg.Addr) (c netpkg.Conn, err error) { switch ra := addri.(type) { case *netpkg.TCPAddr: c, err = netpkg.DialTCP(net, nil, ra) case *netpkg.UDPAddr: c, err = netpkg.DialUDP(net, nil, ra) case *netpkg.IPAddr: c, err = netpkg.DialIP(net, nil, ra) default: err = errors.New("Unknown network address type") } if err != nil { return nil, err } return }
func send(s string) { if nSent > maxSends { log.Printf("sends capped at %d; not sending %s", maxSends, s) return } atomic.AddInt32(&nSent, 1) log.Printf("%20s to %s: %s", "SEND", sendDest.String(), s) conn, err := net.DialIP(groupIPProto, nil, sendDest) if err != nil { log.Panic(err) } defer conn.Close() _, err = conn.Write([]byte(s)) if err != nil { log.Panic(err) } }
func ping(host string) { log.Println("Ping ", host) raddr, err := net.ResolveIPAddr("ip", host) if err != nil { log.Fatalln("resolve ip addr error", err) } else { log.Println("IP:", raddr) } conn, err := net.DialIP("ip4:icmp", nil, raddr) if err != nil { log.Fatalln(err) } var icmp ICMP icmp.Type = 8 icmp.Code = 0 icmp.Checksum = 0 icmp.Identifier = 0 icmp.SequenceNum = 0 var buffer bytes.Buffer binary.Write(&buffer, binary.BigEndian, icmp) icmp.Checksum = CheckSum(buffer.Bytes()) buffer.Reset() binary.Write(&buffer, binary.BigEndian, icmp) log.Println("Runing Ping data ", printByte(buffer.Bytes())) conn.Write(buffer.Bytes()) t_start := time.Now() conn.SetReadDeadline((time.Now().Add(time.Second * 5))) recv := make([]byte, 100) recv_len, err := conn.Read(recv) if err != nil { log.Fatalln(err) } // log.Println("Recv data check error", recv, buffer.Bytes()) // } log.Println("Recv data ", printByte(recv[:recv_len])) t_end := time.Now() dur := t_end.Sub(t_start).Nanoseconds() / 1e6 log.Println("Time spend ms", dur) log.Println("") defer conn.Close() }
func main() { if len(os.Args) != 2 { fmt.Println("Usage:", os.Args[0], "host") os.Exit(1) } addr, err := net.ResolveIPAddr("ip", os.Args[1]) if err != nil { fmt.Println("Resolution error", err.Error()) os.Exit(1) } conn, err := net.DialIP("ip4:icmp", nil, addr) checkError(err) var msg [512]byte msg[0] = 8 msg[1] = 0 msg[2] = 0 msg[3] = 0 msg[4] = 0 msg[5] = 13 msg[6] = 0 msg[7] = 37 len := 8 check := checkSum(msg[0:len]) msg[2] = byte(check >> 8) msg[3] = byte(check & 255) _, err = conn.Write(msg[0:len]) checkError(err) _, err = conn.Read(msg[0:]) checkError(err) fmt.Println("Got response") if msg[5] == 13 { fmt.Println("identifier matches") } if msg[7] == 37 { fmt.Println("Sequence mathces") } os.Exit(0) }
func main() { laddr := &net.IPAddr{IP: net.ParseIP("0.0.0.0")} raddr, err := net.ResolveIPAddr("ip", os.Args[1]) if err != nil { log.Fatalln("parse remote addr error: ", err.Error()) } conn, err := net.DialIP("ip4:icmp", laddr, raddr) if err != nil { log.Fatalln("dial ip failed", err.Error()) return } defer conn.Close() payload, err := (&icmp.Message{ Type: ipv4.ICMPTypeEcho, Code: 0, Body: &icmp.Echo{ ID: 0, Seq: 0, Data: []byte("abcd"), }, }).Marshal(nil) if err != nil { log.Fatalln("marshal echo error: ", err.Error()) } log.Println(payload) numWrite, err := conn.Write(payload) if err != nil { log.Fatalln("write echo request error: ", err.Error()) } log.Println("write size: ", numWrite) numRead, _, err := conn.ReadFrom(payload) if err != nil { log.Fatalln("read echo request error: ", err.Error()) } log.Println("read size: ", numRead) for { } }
func main() { if len(os.Args) != 2 { fmt.Fprintf(os.Stderr, "Usage:%s host", os.Args[0]) } service := os.Args[1] lAddr, err := net.ResolveTCPAddr("ip4", service) checkError(err) name, err := os.Hostname() checkError(err) rAddr, err := net.ResolveIPAddr("ip4", name) checkError(err) conn, err := net.DialIP("ip4:ip", lAddr, rAddr) checkError(err) _, err = conn.WriteToIP([]byte("Hello Server!"), rAddr) checkError(err) var buf [512]byte n, addr, err := conn.ReadFromIP(buf[0:]) checkError(err) fmt.Println("Reply form server", addr.String(), string(buf[0:n])) conn.Close() os.Exit(0) }
func NewICMPPacketClient(server string) (*ICMPPacketClient, error) { addr, err := net.ResolveIPAddr("ip", server) if err != nil { return nil, err } conn, err := net.DialIP("ip:icmp", nil, addr) if err != nil { return nil, err } // TODO: start the read process. send_ch := make(chan []byte) recv_ch := make(chan []byte) client := &ICMPPacketClient{conn, send_ch, recv_ch, true} // TODO: cross-platform! old_val, err := ChangeIgnorePings(false) if err != nil { client.old_icmp_val = old_val } return nil, nil }
func sendICMPPacket(host string, count int) StasticData { addr, err := net.ResolveIPAddr("ip", host) if err != nil { fmt.Println("Resolve Address Error", err.Error()) os.Exit(1) } laddr := net.IPAddr{IP: net.ParseIP("0.0.0.0")} conn, err := net.DialIP("ip4:icmp", &laddr, addr) checkErr(err) defer conn.Close() var icmp ICMP icmp.Type = 8 icmp.Code = 0 icmp.Checksum = 0 icmp.Identifier = 13 icmp.Sequence = 40 var buffer bytes.Buffer binary.Write(&buffer, binary.BigEndian, icmp) icmp.Checksum = checksum(buffer.Bytes()) buffer.Reset() binary.Write(&buffer, binary.BigEndian, icmp) var result StasticData result.Host = host result.Count = int32(count) result.DurationList = list.New() fmt.Printf("\nPing %s (%s) 0 bytes of data\n", host, addr.IP.To16()) for i := 0; i < count; i++ { _, err = conn.Write(buffer.Bytes()) if err != nil { fmt.Fprintf(os.Stderr, "Error : %s\n", err.Error()) continue } tNow := time.Now() result.SendedPackets++ // fmt.Println("Send icmp packet successfully") //read timeout //TODO: could be configurable conn.SetReadDeadline(tNow.Add(1 * time.Second)) recv := make([]byte, 512) _, err = conn.Read(recv) if err != nil { fmt.Fprintf(os.Stderr, "Error : %s\n", err.Error()) continue } tEnd := time.Now() duration := int32(tEnd.Sub(tNow).Nanoseconds() / (1000 * 1000)) fmt.Printf("from %s (%s) : time=%dms\n", host, addr.String(), duration) result.DurationList.PushBack(duration) // fmt.Println(recv) } return result }
func (self *HikarianIcmp) transportClient(clientConn *net.TCPConn) { wb := make([]byte, 10240) host, port, err := net.SplitHostPort(clientConn.RemoteAddr().String()) if err != nil { log.Fatal("split host port error: ", err.Error()) return } ip4 := strings.Split(host, ".") id := 0 for index, value := range ip4 { log.Println(index, value) i, err := strconv.Atoi(value) if err != nil { log.Println("strconv ip error: ", err.Error()) continue } id += int(uint(i) >> uint(index)) } seq, err := strconv.Atoi(port) if err != nil { log.Println("strconv port error: ", err.Error()) } //server laddr := &net.IPAddr{IP: net.ParseIP("0.0.0.0")} raddr, err := net.ResolveIPAddr("ip", self.server) if err != nil { log.Fatalln("parse remote addr error: ", err.Error()) } serverConn, err := net.DialIP("ip4:icmp", laddr, raddr) if err != nil { log.Fatalln("dial ip failed", err.Error()) return } // defer serverConn.Close() readChannel := make(chan []byte) go func() { for { rb := make([]byte, 1024) log.Println("wait client data") nr, _, err := serverConn.ReadFrom(rb) log.Println("get client data size ", nr) if err != nil { if err != io.EOF { log.Println("read server error: ", err) break } } reply, err := icmp.ParseMessage(ProtocolICMP, rb) if err != nil { log.Println("parse icmp echo reply error: ", err.Error()) break } if reply.Code != MagicCode { break } body, err := reply.Body.Marshal(ProtocolICMP) if err != nil { log.Println("marshal icmp echo reply body error: ", err.Error()) break } log.Printf("get echo reply id:%d and seq:%d", binary.BigEndian.Uint16(body[0:2]), binary.BigEndian.Uint16(body[2:4])) if binary.BigEndian.Uint16(body[0:2]) == uint16(id) && binary.BigEndian.Uint16(body[2:4]) == uint16(seq) { log.Println("right") readChannel <- body[4 : nr-4] // break } else { log.Println("receive other") continue } } close(readChannel) }() go func() { for { body, ok := <-readChannel if ok == false { return } nr, err := clientConn.Write(body) if err != nil { log.Println("write client error: ", err.Error()) return } log.Println("get echo reply size ", nr) } }() done := make(chan bool) go func() { for { size := 0 rb := make([]byte, 1024) log.Println("wait client") nr, err := clientConn.Read(rb) log.Println("get client data size ", nr) if err != nil { if err != io.EOF { log.Println("read server error: ", err.Error()) break } else { log.Println("EOF") break } } if nr > 0 { wb = append(wb[:size], rb[:nr]...) size += nr } log.Printf("set echo request id:%d and seq:%d", id, seq) payload, err := (&icmp.Message{ Type: ipv4.ICMPTypeEcho, Code: MagicCode, Body: &icmp.Echo{ ID: id, Seq: seq, Data: wb[:size], }, }).Marshal(nil) if err != nil { log.Fatalln("marshal echo error: ", err.Error()) } nw, err := serverConn.Write(payload) if err != nil { log.Fatalln("write echo request error: ", err.Error()) } log.Println("write server ", nw) } done <- true }() <-done }
func main() { usage := `Ping. Usage: ping [--count COUNT] DESTINATION Options: -h --help Show this message. -c, --count COUNT Send this many pings [default: 20].` arguments, _ := docopt.Parse(usage, nil, true, "Ping", false) host := arguments["DESTINATION"].(string) numPings := 20 if arguments["--count"] != nil { numPings, _ = strconv.Atoi(arguments["--count"].(string)) } rAddr, err := net.ResolveIPAddr("ip4", host) if err != nil { panic(err) } fmt.Printf("PING %s (%s)\n", host, rAddr) conn, err := net.DialIP("ip4:icmp", nil, rAddr) if err != nil { panic(err) } defer conn.Close() pid := os.Getpid() var id1 = byte(pid & 0xff00 >> 8) var id2 = byte(pid & 0xff) var timeout = 1 * time.Second var interval = 1 * time.Second var messageLength = 8 pingTimes := []time.Duration{} for i := 0; i < numPings; i++ { msg := MakeEchoRequest(i, messageLength, id1, id2) startTime := time.Now() deadline := startTime.Add(timeout) conn.SetDeadline(deadline) if _, err = conn.Write(msg[0:messageLength]); err != nil { continue } response := make([]byte, 64) for { numRead, _, err := conn.ReadFrom(response) if err != nil { panic(err) } if response[0] == 0 { duration := time.Since(startTime) fmt.Printf("%d bytes from %s (%s): time=%v\n", numRead, host, rAddr, duration) pingTimes = append(pingTimes, duration) } break } time.Sleep(interval) } fmt.Printf("--- %s statistics ---\n", host) total, min, max, avg := ComputeStats(pingTimes) fmt.Printf("total = %v\n", total) fmt.Printf("rtt min = %v\n", min) fmt.Printf("rtt max = %v\n", max) fmt.Printf("rtt avg = %v\n", avg) }
func fillARP(ifin string) { defer wg.Done() ifi, err := net.InterfaceByName(ifin) if err != nil { log.Fatal(err) } ifat, err := ifi.Addrs() if err != nil { log.Fatal(err) } var bs = []byte{0} for _, addr := range ifat { saddr := addr.String()[:strings.IndexRune(addr.String(), '/')] if strings.Contains(saddr, ":") { continue } la := &net.IPAddr{ IP: net.ParseIP(saddr), } maskSize, err := strconv.ParseUint(addr.String()[len(saddr)+1:], 10, 6) if err != nil { log.Fatal(err) } mSizeLeft := byte(maskSize) mask := make(net.IPMask, 4) var lastMaskOct int for lastMaskOct = 12; lastMaskOct < 16; lastMaskOct++ { if n := mSizeLeft - 8; n > 0 && n <= 32 { mSizeLeft = n mask[lastMaskOct-12] = 255 } else { mask[lastMaskOct-12] = ^byte(math.Pow(2, float64((8-mSizeLeft))) - 1) break } } var ping func(net.IP, int) ping = func(rip net.IP, oct int) { var start byte var max byte if oct == lastMaskOct { start = mask[lastMaskOct-12] & rip[lastMaskOct] max = ^mask[lastMaskOct-12] + start } else { max = 255 } for rip[oct] = start; rip[oct] <= max; rip[oct]++ { nip := make(net.IP, 16) copy(nip, rip) if oct != 15 { ping(nip, oct+1) continue } wg.Add(1) go func(rip net.IP) { defer wg.Done() ra := &net.IPAddr{ IP: net.ParseIP(rip.String()), } ipc, err := net.DialIP("ip4", la, ra) if err != nil { log.Println(err) } defer ipc.Close() ipc.Write(bs) }(nip) if rip[oct] == 255 { break } time.Sleep(time.Millisecond * 20) } } ping(net.ParseIP(la.IP.Mask(mask).String()), lastMaskOct) } }
func Pinger(laddr, address string, timeout int) error { // c, err := net.Dial("ip4:icmp", address) lip, e := net.ResolveIPAddr("ip4", laddr) if e != nil { return e } rip, e := net.ResolveIPAddr("ip4", address) if e != nil { return e } c, err := net.DialIP("ip4:icmp", lip, rip) if err != nil { return err } c.SetDeadline(time.Now().Add(time.Duration(timeout) * time.Second)) defer c.Close() typ := icmpv4EchoRequest xid, xseq := os.Getpid()&0xffff, 1 wb, err := (&icmpMessage{ Type: typ, Code: 0, Body: &icmpEcho{ ID: xid, Seq: xseq, Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3), }, }).Marshal() if err != nil { return err } tries := 3 for i := 0; i < tries; i++ { if _, err = c.Write(wb); err != nil { return err } var m *icmpMessage rb := make([]byte, 20+len(wb)) c.SetReadDeadline(time.Now().Add(time.Duration(timeout) * time.Millisecond)) _, err = c.Read(rb) if err != nil { if nerr, ok := err.(net.Error); ok && nerr.Timeout() && i < 2 { continue } else { return err } } rb = ipv4Payload(rb) if m, err = parseICMPMessage(rb); err != nil { return err } switch m.Type { case icmpv4EchoRequest, icmpv6EchoRequest: } break } return nil }
func main() { if 2 > len(os.Args) { fmt.Println("input: IPAddr") return } var ( icmp ICMP laddr = net.IPAddr{IP: net.ParseIP("0.0.0.0")} raddr, _ = net.ResolveIPAddr("ip", os.Args[1]) ) conn, err := net.DialIP("ip4:icmp", &laddr, raddr) checkErr(err) icmp.Type = 8 icmp.Code = 0 icmp.Checksum = 0 icmp.Identifier = 0 icmp.SequenceNum = 0 var buff bytes.Buffer binary.Write(&buff, binary.BigEndian, icmp) icmp.Checksum = Checksum(buff.Bytes()) buff.Reset() binary.Write(&buff, binary.BigEndian, icmp) fmt.Println("\n正在 Ping %s 具有 0 字节的数据:\n", raddr.String()) recv := make([]byte, 1024) statistic := list.New() sended_packets := 0 for i := 4; i > 0; i-- { if _, err := conn.Write(buff.Bytes()); err != nil { fmt.Println(err.Error()) return } sended_packets++ t_start := time.Now() conn.SetReadDeadline((time.Now().Add(time.Second * 5))) _, err := conn.Read(recv) if err != nil { fmt.Println("请求超时") continue } t_end := time.Now() dur := t_end.Sub(t_start).Nanoseconds() / 1e6 fmt.Printf("来自 %s 的回复:时间 = %dms\n", raddr.String(), dur) statistic.PushBack(dur) } defer conn.Close() defer func() { fmt.Println("") //信息统计 var min, max, sum int64 if statistic.Len() == 0 { min, max, sum = 0, 0, 0 } else { min, max, sum = statistic.Front().Value.(int64), statistic.Front().Value.(int64), int64(0) } for v := statistic.Front(); v != nil; v = v.Next() { val := v.Value.(int64) switch { case val < min: min = val case val > max: max = val } sum = sum + val } recved, losted := statistic.Len(), sended_packets-statistic.Len() fmt.Printf("%s 的 Ping 统计信息:\n 数据包:已发送 = %d,已接收 = %d,丢失 = %d (%.1f%% 丢失),\n往返行程的估计时间(以毫秒为单位):\n 最短 = %dms,最长 = %dms,平均 = %.0fms\n", raddr.String(), sended_packets, recved, losted, float32(losted)/float32(sended_packets)*100, min, max, float32(sum)/float32(recved), ) }() }
// Ping func Ping(addr string, i int) bool { // *IPAddr raddr, e := net.ResolveIPAddr("ip4", addr) if e != nil { return false } // *IPConn ipconn, ee := net.DialIP("ip4:icmp", nil, raddr) if ee != nil { return false } // 保证连接正常关闭 defer ipconn.Close() // PID sendid := os.Getpid() & 0xffff sendseq := 1 pingpktlen := 64 for { sendpkt := makePingRequest(sendid, sendseq, pingpktlen, []byte("Go Ping")) // 发送请求 n, err := ipconn.WriteToIP(sendpkt, raddr) if err != nil || n != pingpktlen { break } // 超时 ipconn.SetDeadline(time.Now().Add(5 * time.Second)) // 返回数据 resp := make([]byte, 1024) for { // 读取返回 _, _, err := ipconn.ReadFrom(resp) if err != nil { break } // 判断状态 if resp[0] != ICMP_ECHO_REPLY { continue } // 判断状态 rcvid, rcvseq := parsePingReply(resp) if rcvid != sendid || rcvseq != sendseq { break } // 成功返回 return true } // 执行次数内未成功返回 if i == sendseq { break } // 计数器 sendseq++ } // 失败返回 return false }
func PingIP(hostname string, raddr *net.IPAddr, pcount int, debug bool) (sent int, received int, etimes []float64) { // Make the IP connection to the destination host ipconn, err := net.DialIP("ip4:icmp", nil, raddr) if err != nil { fmt.Printf("could not connect to %s: %v\n", raddr.IP, err) return } sendid := os.Getpid() & 0xffff sendseq := 1 pingpktlen := 64 //if debug { fmt.Printf("PING %s (%s): %d data bytes\n", hostname, raddr.String(), pingpktlen-8) //} for { var check4reply bool var etime float64 // Generate our ICMP packet sendpkt := makePingRequest(sendid, sendseq, pingpktlen, []byte("Go Ping")) // Start timer start := time.Now() // Send ICMP packet n, err := ipconn.Write(sendpkt) // Err out if we couldn't send the full packet size if err != nil || n != pingpktlen { etime = elapsedTime(start) fmt.Printf("0 bytes from %s: icmp_req=%d time=%.3f ms ERR: Network is down\n", raddr.IP, sendseq, etime) } else { // We will check this flag later to see if we need to wait for a returned packet check4reply = true } // increment our sent counter sent++ // set a 0.5 second timer as our max packet reply wait time var deadline = start.Add(500 * time.Millisecond) ipconn.SetReadDeadline(deadline) // Read response packet (or process timeout if it occurs) resp := make([]byte, 1024) for { if check4reply == false { break } n, _, err := ipconn.ReadFrom(resp) if err != nil { // Could not read response packet etime = elapsedTime(start) if debug { fmt.Printf("%d bytes from %s: icmp_req=%d time=%.3f ms ERR: %s\n", n, raddr.IP, sendseq, etime, err.Error()) } break } else { // Response was okay } if resp[0] != ICMP_ECHO_REPLY { // Skip non-ICMP packets continue } rcvid, rcvseq := parsePingReply(resp) if rcvid != sendid || rcvseq != sendseq { etime = elapsedTime(start) if debug { fmt.Printf("%d bytes from %s: icmp_req=%d time=%.3f ms ERR: Out of sequence (0x%x,0x%x)\n", n, raddr.IP, sendseq, etime, rcvid, rcvseq) } } else { // Packet reply came back okay etime = elapsedTime(start) if debug { fmt.Printf("%d bytes from %s: icmp_req=%d time=%.3f ms\n", n, raddr.IP, sendseq, etime) } received++ etimes = append(etimes, etime) } break } sendseq++ if sendseq > pcount { // We've reached the maximum number of packets to send so return return } else { // Sleep 1 second before moving onto the next packet time.Sleep(1 * time.Second) } } }