gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }