/
icmp.go
77 lines (75 loc) · 1.46 KB
/
icmp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package main
import (
"bytes"
"fmt"
"io"
"net"
"os"
)
func main() {
if len(os.Args) != 2 {
fmt.Println("Usage: ", os.Args[0], "host")
os.Exit(1)
}
service := os.Args[1]
conn, err := net.Dial("ip4:icmp", service)
checkError(err)
var msg [512]byte
msg[0] = 8 // echo
msg[1] = 0 // code 0
msg[2] = 0 // checksum
msg[3] = 0 // checksum
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 checkSum(msg []byte) uint16 {
sum := 0
// 先假设为偶数
for n := 1; n < len(msg)-1; n += 2 {
sum += int(msg[n])*256 + int(msg[n+1])
}
sum = (sum >> 16) + (sum & 0xffff)
sum += (sum >> 16)
var answer uint16 = uint16(^sum)
return answer
}
func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
os.Exit(1)
}
}
func readFully(conn net.Conn) ([]byte, error) {
defer conn.Close()
result := bytes.NewBuffer(nil)
var buf [512]byte
for {
n, err := conn.Read(buf[0:])
result.Write(buf[0:n])
if err != nil {
if err == io.EOF {
break
}
return nil, err
}
}
return result.Bytes(), nil
}