golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/ipv4/control_unix.go (about)

     1  // Copyright 2012 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  //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
     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  }