-
Notifications
You must be signed in to change notification settings - Fork 1
/
send.go
78 lines (73 loc) · 1.59 KB
/
send.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
78
package gmtr
import (
ipv42 "github.com/neo-hu/gmtr/net/ipv4"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
"syscall"
)
func (m *GMtr) sendV6() error {
seq := m.incr()
sv := &seqValue{
ttl: m.currentTTL,
ping: m.currentCount,
time: m.lastSendTime,
evTime: m.lastSendTime.Add(m.timeout),
}
m.seqMap.Store(seq, sv)
m.evEnqueue(sv)
m.setSendResult(m.currentTTL)
b, err := (&icmp.Message{
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
Body: &icmp.Echo{
ID: m.ident, Seq: seq,
Data: make([]byte, m.dataSize),
},
}).Marshal(nil)
if err != nil {
return err
}
err = syscall.SetsockoptInt(m.socketFd, syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, m.currentTTL)
if err != nil {
return err
}
return syscall.Sendto(m.socketFd, b, 0, m.sa)
}
func (m *GMtr) sendV4() error {
seq := m.incr()
sv := &seqValue{
ttl: m.currentTTL,
ping: m.currentCount,
time: m.lastSendTime,
evTime: m.lastSendTime.Add(m.timeout),
}
m.seqMap.Store(seq, sv)
m.evEnqueue(sv)
m.setSendResult(m.currentTTL)
b, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
Body: &icmp.Echo{
ID: m.ident, Seq: seq,
Data: make([]byte, m.dataSize),
},
}).Marshal(nil)
if err != nil {
return err
}
header := &ipv4.Header{
Version: ipv4.Version,
Len: ipv4.HeaderLen,
Protocol: syscall.IPPROTO_ICMP,
TotalLen: ipv4.HeaderLen + len(b),
ID: seq + 3232,
TTL: m.currentTTL,
Dst: m.ip.To4(),
}
return ipv42.WriteTo(m.socketFd, header, b, nil)
}
func (m *GMtr) incr() int {
m.Lock()
defer m.Unlock()
m.cnt += 1
return m.cnt
}