...
1
2
3
4
5
6
7 package ipv4
8
9 import (
10 "unsafe"
11
12 "golang.org/x/net/internal/iana"
13 "golang.org/x/net/internal/socket"
14
15 "golang.org/x/sys/unix"
16 )
17
18 func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
19 opt.Lock()
20 defer opt.Unlock()
21 if so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 {
22 if err := so.SetInt(c, boolint(on)); err != nil {
23 return err
24 }
25 if on {
26 opt.set(FlagTTL)
27 } else {
28 opt.clear(FlagTTL)
29 }
30 }
31 if so, ok := sockOpts[ssoPacketInfo]; ok {
32 if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
33 if err := so.SetInt(c, boolint(on)); err != nil {
34 return err
35 }
36 if on {
37 opt.set(cf & (FlagSrc | FlagDst | FlagInterface))
38 } else {
39 opt.clear(cf & (FlagSrc | FlagDst | FlagInterface))
40 }
41 }
42 } else {
43 if so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 {
44 if err := so.SetInt(c, boolint(on)); err != nil {
45 return err
46 }
47 if on {
48 opt.set(FlagDst)
49 } else {
50 opt.clear(FlagDst)
51 }
52 }
53 if so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 {
54 if err := so.SetInt(c, boolint(on)); err != nil {
55 return err
56 }
57 if on {
58 opt.set(FlagInterface)
59 } else {
60 opt.clear(FlagInterface)
61 }
62 }
63 }
64 return nil
65 }
66
67 func marshalTTL(b []byte, cm *ControlMessage) []byte {
68 m := socket.ControlMessage(b)
69 m.MarshalHeader(iana.ProtocolIP, unix.IP_RECVTTL, 1)
70 return m.Next(1)
71 }
72
73 func parseTTL(cm *ControlMessage, b []byte) {
74 cm.TTL = int(*(*byte)(unsafe.Pointer(&b[:1][0])))
75 }
76
View as plain text