github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/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  // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
     6  
     7  package ipv4
     8  
     9  import (
    10  	"unsafe"
    11  
    12  	"github.com/Andyfoo/golang/x/net/internal/iana"
    13  	"github.com/Andyfoo/golang/x/net/internal/socket"
    14  )
    15  
    16  func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
    17  	opt.Lock()
    18  	defer opt.Unlock()
    19  	if so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 {
    20  		if err := so.SetInt(c, boolint(on)); err != nil {
    21  			return err
    22  		}
    23  		if on {
    24  			opt.set(FlagTTL)
    25  		} else {
    26  			opt.clear(FlagTTL)
    27  		}
    28  	}
    29  	if so, ok := sockOpts[ssoPacketInfo]; ok {
    30  		if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
    31  			if err := so.SetInt(c, boolint(on)); err != nil {
    32  				return err
    33  			}
    34  			if on {
    35  				opt.set(cf & (FlagSrc | FlagDst | FlagInterface))
    36  			} else {
    37  				opt.clear(cf & (FlagSrc | FlagDst | FlagInterface))
    38  			}
    39  		}
    40  	} else {
    41  		if so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 {
    42  			if err := so.SetInt(c, boolint(on)); err != nil {
    43  				return err
    44  			}
    45  			if on {
    46  				opt.set(FlagDst)
    47  			} else {
    48  				opt.clear(FlagDst)
    49  			}
    50  		}
    51  		if so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 {
    52  			if err := so.SetInt(c, boolint(on)); err != nil {
    53  				return err
    54  			}
    55  			if on {
    56  				opt.set(FlagInterface)
    57  			} else {
    58  				opt.clear(FlagInterface)
    59  			}
    60  		}
    61  	}
    62  	return nil
    63  }
    64  
    65  func marshalTTL(b []byte, cm *ControlMessage) []byte {
    66  	m := socket.ControlMessage(b)
    67  	m.MarshalHeader(iana.ProtocolIP, sysIP_RECVTTL, 1)
    68  	return m.Next(1)
    69  }
    70  
    71  func parseTTL(cm *ControlMessage, b []byte) {
    72  	cm.TTL = int(*(*byte)(unsafe.Pointer(&b[:1][0])))
    73  }