add ping functions

master v0.1.1
Starainrt 3 years ago
parent 8dab0b269e
commit b4bffa978c

@ -0,0 +1,97 @@
package starnet
import (
"bytes"
"encoding/binary"
"net"
"time"
)
type ICMP struct {
Type uint8
Code uint8
CheckSum uint16
Identifier uint16
SequenceNum uint16
}
func getICMP(seq uint16) ICMP {
icmp := ICMP{
Type: 8,
Code: 0,
CheckSum: 0,
Identifier: 0,
SequenceNum: seq,
}
var buffer bytes.Buffer
binary.Write(&buffer, binary.BigEndian, icmp)
icmp.CheckSum = checkSum(buffer.Bytes())
buffer.Reset()
return icmp
}
func sendICMPRequest(icmp ICMP, destAddr *net.IPAddr, timeout time.Duration) (PingResult, error) {
var res PingResult
conn, err := net.DialIP("ip:icmp", nil, destAddr)
if err != nil {
return res, err
}
defer conn.Close()
var buffer bytes.Buffer
binary.Write(&buffer, binary.BigEndian, icmp)
if _, err := conn.Write(buffer.Bytes()); err != nil {
return res, err
}
tStart := time.Now()
conn.SetReadDeadline((time.Now().Add(timeout)))
recv := make([]byte, 1024)
res.RecvCount, err = conn.Read(recv)
if err != nil {
return res, err
}
tEnd := time.Now()
res.Duration = tEnd.Sub(tStart)
return res, err
}
func checkSum(data []byte) uint16 {
var (
sum uint32
length int = len(data)
index int
)
for length > 1 {
sum += uint32(data[index])<<8 + uint32(data[index+1])
index += 2
length -= 2
}
if length > 0 {
sum += uint32(data[index])
}
sum += (sum >> 16)
return uint16(^sum)
}
type PingResult struct {
Duration time.Duration
RecvCount int
}
func Ping(ip string, seq int, timeout time.Duration) (PingResult, error) {
var res PingResult
ipAddr, err := net.ResolveIPAddr("ip", ip)
if err != nil {
return res, err
}
icmp := getICMP(uint16(seq))
return sendICMPRequest(icmp, ipAddr, timeout)
}

@ -0,0 +1,11 @@
package starnet
import (
"fmt"
"testing"
"time"
)
func Test_Ping(t *testing.T) {
fmt.Println(Ping("baidu.com", 0, time.Second*2))
}
Loading…
Cancel
Save