|
19 | 19 | package lmap |
20 | 20 |
|
21 | 21 | import ( |
22 | | - "bytes" |
23 | 22 | "encoding/binary" |
| 23 | + "golang.org/x/net/icmp" |
24 | 24 | "log" |
25 | 25 | "net" |
26 | 26 | "time" |
27 | 27 | ) |
28 | 28 |
|
29 | 29 | func Ping(ip net.IP) bool { |
30 | | - var icmp ICMP |
31 | | - //开始填充数据包 |
32 | | - icmp.Type = 8 //8->echo message 0->reply message |
| 30 | + recvBuf := make([]byte, 8) |
33 | 31 |
|
34 | | - recvBuf := make([]byte, 32) |
35 | | - var buffer bytes.Buffer |
| 32 | + // Start listening for icmp replies |
| 33 | + conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0") |
36 | 34 |
|
37 | | - //先在buffer中写入icmp数据报求去校验和 |
38 | | - _ = binary.Write(&buffer, binary.BigEndian, icmp) |
39 | | - icmp.Checksum = checkSum(buffer.Bytes()) |
40 | | - //然后清空buffer并把求完校验和的icmp数据报写入其中准备发送 |
41 | | - buffer.Reset() |
42 | | - _ = binary.Write(&buffer, binary.BigEndian, icmp) |
43 | | - |
44 | | - conn, err := net.DialTimeout("ip4:icmp", ip.String(), 1*time.Second) |
45 | 35 | if err != nil { |
| 36 | + log.Println("dial error:", err) |
46 | 37 | return false |
47 | 38 | } |
48 | | - _, err = conn.Write(buffer.Bytes()) |
| 39 | + defer conn.Close() |
| 40 | + |
| 41 | + sendBytes := []byte{8, 0, 247, 255, 0, 0, 0, 0} |
| 42 | + //expectCheckSum := int(checkSum([]byte{0, 0, 0, 0, 0, 0, 0, 0})) |
| 43 | + expectCheckSum := 65535 |
| 44 | + |
| 45 | + _, err = conn.WriteTo(sendBytes, &net.IPAddr{ |
| 46 | + IP: ip, |
| 47 | + }) |
49 | 48 | if err != nil { |
50 | | - log.Println("conn.Write error:", err) |
51 | 49 | return false |
52 | 50 | } |
53 | 51 | _ = conn.SetReadDeadline(time.Now().Add(time.Second * 2)) |
54 | | - num, err := conn.Read(recvBuf) |
| 52 | + |
| 53 | + _, _, err = conn.ReadFrom(recvBuf) |
55 | 54 | if err != nil { |
56 | 55 | return false |
57 | 56 | } |
58 | 57 |
|
59 | | - _ = conn.SetReadDeadline(time.Time{}) |
| 58 | + recvType := recvBuf[0] |
| 59 | + recvCheckSum := int(binary.BigEndian.Uint16(recvBuf[2:4])) |
60 | 60 |
|
61 | | - return string(recvBuf[0:num]) != "" |
62 | | -} |
| 61 | + _ = conn.SetReadDeadline(time.Time{}) |
63 | 62 |
|
64 | | -func checkSum(data []byte) uint16 { |
65 | | - var ( |
66 | | - sum uint32 |
67 | | - length = len(data) |
68 | | - index int |
69 | | - ) |
70 | | - for length > 1 { |
71 | | - sum += uint32(data[index])<<8 + uint32(data[index+1]) |
72 | | - index += 2 |
73 | | - length -= 2 |
| 63 | + if recvType != 0 { |
| 64 | + return false |
74 | 65 | } |
75 | | - if length > 0 { |
76 | | - sum += uint32(data[index]) |
| 66 | + |
| 67 | + if recvCheckSum != expectCheckSum { |
| 68 | + return false |
77 | 69 | } |
78 | | - sum += sum >> 16 |
79 | 70 |
|
80 | | - return uint16(^sum) |
| 71 | + return true |
81 | 72 | } |
| 73 | + |
| 74 | +//func checkSum(data []byte) uint16 { |
| 75 | +// var ( |
| 76 | +// sum uint32 |
| 77 | +// length = len(data) |
| 78 | +// index int |
| 79 | +// ) |
| 80 | +// for length > 1 { |
| 81 | +// sum += uint32(data[index])<<8 + uint32(data[index+1]) |
| 82 | +// index += 2 |
| 83 | +// length -= 2 |
| 84 | +// } |
| 85 | +// if length > 0 { |
| 86 | +// sum += uint32(data[index]) |
| 87 | +// } |
| 88 | +// sum += sum >> 16 |
| 89 | +// |
| 90 | +// return uint16(^sum) |
| 91 | +//} |
0 commit comments