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