control_zos.go (2042B)
1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 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 }