...
1
2
3
4
5 package ipv4
6
7 import (
8 "net"
9 "unsafe"
10
11 "golang.org/x/net/internal/iana"
12 "golang.org/x/net/internal/socket"
13
14 "golang.org/x/sys/unix"
15 )
16
17 func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
18 m := socket.ControlMessage(b)
19 m.MarshalHeader(iana.ProtocolIP, unix.IP_PKTINFO, sizeofInetPktinfo)
20 if cm != nil {
21 pi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0]))
22 if ip := cm.Src.To4(); ip != nil {
23 copy(pi.Addr[:], ip)
24 }
25 if cm.IfIndex > 0 {
26 pi.setIfindex(cm.IfIndex)
27 }
28 }
29 return m.Next(sizeofInetPktinfo)
30 }
31
32 func parsePacketInfo(cm *ControlMessage, b []byte) {
33 pi := (*inetPktinfo)(unsafe.Pointer(&b[0]))
34 cm.IfIndex = int(pi.Ifindex)
35 if len(cm.Dst) < net.IPv4len {
36 cm.Dst = make(net.IP, net.IPv4len)
37 }
38 copy(cm.Dst, pi.Addr[:])
39 }
40
41 func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
42 opt.Lock()
43 defer opt.Unlock()
44 if so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 {
45 if err := so.SetInt(c, boolint(on)); err != nil {
46 return err
47 }
48 if on {
49 opt.set(FlagTTL)
50 } else {
51 opt.clear(FlagTTL)
52 }
53 }
54 if so, ok := sockOpts[ssoPacketInfo]; ok {
55 if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
56 if err := so.SetInt(c, boolint(on)); err != nil {
57 return err
58 }
59 if on {
60 opt.set(cf & (FlagSrc | FlagDst | FlagInterface))
61 } else {
62 opt.clear(cf & (FlagSrc | FlagDst | FlagInterface))
63 }
64 }
65 } else {
66 if so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 {
67 if err := so.SetInt(c, boolint(on)); err != nil {
68 return err
69 }
70 if on {
71 opt.set(FlagDst)
72 } else {
73 opt.clear(FlagDst)
74 }
75 }
76 if so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 {
77 if err := so.SetInt(c, boolint(on)); err != nil {
78 return err
79 }
80 if on {
81 opt.set(FlagInterface)
82 } else {
83 opt.clear(FlagInterface)
84 }
85 }
86 }
87 return nil
88 }
89
View as plain text