Source file src/pkg/net/sockoptip.go
1 // Copyright 2011 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 darwin freebsd linux netbsd openbsd windows 6 7 // IP-level socket options 8 9 package net 10 11 import ( 12 "os" 13 "syscall" 14 ) 15 16 func ipv4TOS(fd *netFD) (int, error) { 17 if err := fd.incref(false); err != nil { 18 return 0, err 19 } 20 defer fd.decref() 21 v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_TOS) 22 if err != nil { 23 return 0, os.NewSyscallError("getsockopt", err) 24 } 25 return v, nil 26 } 27 28 func setIPv4TOS(fd *netFD, v int) error { 29 if err := fd.incref(false); err != nil { 30 return err 31 } 32 defer fd.decref() 33 err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_TOS, v) 34 if err != nil { 35 return os.NewSyscallError("setsockopt", err) 36 } 37 return nil 38 } 39 40 func ipv4TTL(fd *netFD) (int, error) { 41 if err := fd.incref(false); err != nil { 42 return 0, err 43 } 44 defer fd.decref() 45 v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_TTL) 46 if err != nil { 47 return 0, os.NewSyscallError("getsockopt", err) 48 } 49 return v, nil 50 } 51 52 func setIPv4TTL(fd *netFD, v int) error { 53 if err := fd.incref(false); err != nil { 54 return err 55 } 56 defer fd.decref() 57 err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_TTL, v) 58 if err != nil { 59 return os.NewSyscallError("setsockopt", err) 60 } 61 return nil 62 } 63 64 func joinIPv4Group(fd *netFD, ifi *Interface, ip IP) error { 65 mreq := &syscall.IPMreq{Multiaddr: [4]byte{ip[0], ip[1], ip[2], ip[3]}} 66 if err := setIPv4MreqToInterface(mreq, ifi); err != nil { 67 return err 68 } 69 if err := fd.incref(false); err != nil { 70 return err 71 } 72 defer fd.decref() 73 return os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreq)) 74 } 75 76 func leaveIPv4Group(fd *netFD, ifi *Interface, ip IP) error { 77 mreq := &syscall.IPMreq{Multiaddr: [4]byte{ip[0], ip[1], ip[2], ip[3]}} 78 if err := setIPv4MreqToInterface(mreq, ifi); err != nil { 79 return err 80 } 81 if err := fd.incref(false); err != nil { 82 return err 83 } 84 defer fd.decref() 85 return os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_DROP_MEMBERSHIP, mreq)) 86 } 87 88 func ipv6HopLimit(fd *netFD) (int, error) { 89 if err := fd.incref(false); err != nil { 90 return 0, err 91 } 92 defer fd.decref() 93 v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS) 94 if err != nil { 95 return 0, os.NewSyscallError("getsockopt", err) 96 } 97 return v, nil 98 } 99 100 func setIPv6HopLimit(fd *netFD, v int) error { 101 if err := fd.incref(false); err != nil { 102 return err 103 } 104 defer fd.decref() 105 err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_UNICAST_HOPS, v) 106 if err != nil { 107 return os.NewSyscallError("setsockopt", err) 108 } 109 return nil 110 } 111 112 func ipv6MulticastInterface(fd *netFD) (*Interface, error) { 113 if err := fd.incref(false); err != nil { 114 return nil, err 115 } 116 defer fd.decref() 117 v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_IF) 118 if err != nil { 119 return nil, os.NewSyscallError("getsockopt", err) 120 } 121 if v == 0 { 122 return nil, nil 123 } 124 ifi, err := InterfaceByIndex(v) 125 if err != nil { 126 return nil, err 127 } 128 return ifi, nil 129 } 130 131 func setIPv6MulticastInterface(fd *netFD, ifi *Interface) error { 132 var v int 133 if ifi != nil { 134 v = ifi.Index 135 } 136 if err := fd.incref(false); err != nil { 137 return err 138 } 139 defer fd.decref() 140 err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_IF, v) 141 if err != nil { 142 return os.NewSyscallError("setsockopt", err) 143 } 144 return nil 145 } 146 147 func ipv6MulticastHopLimit(fd *netFD) (int, error) { 148 if err := fd.incref(false); err != nil { 149 return 0, err 150 } 151 defer fd.decref() 152 v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_HOPS) 153 if err != nil { 154 return 0, os.NewSyscallError("getsockopt", err) 155 } 156 return v, nil 157 } 158 159 func setIPv6MulticastHopLimit(fd *netFD, v int) error { 160 if err := fd.incref(false); err != nil { 161 return err 162 } 163 defer fd.decref() 164 err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_HOPS, v) 165 if err != nil { 166 return os.NewSyscallError("setsockopt", err) 167 } 168 return nil 169 } 170 171 func ipv6MulticastLoopback(fd *netFD) (bool, error) { 172 if err := fd.incref(false); err != nil { 173 return false, err 174 } 175 defer fd.decref() 176 v, err := syscall.GetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_LOOP) 177 if err != nil { 178 return false, os.NewSyscallError("getsockopt", err) 179 } 180 return v == 1, nil 181 } 182 183 func setIPv6MulticastLoopback(fd *netFD, v bool) error { 184 if err := fd.incref(false); err != nil { 185 return err 186 } 187 defer fd.decref() 188 err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_LOOP, boolint(v)) 189 if err != nil { 190 return os.NewSyscallError("setsockopt", err) 191 } 192 return nil 193 } 194 195 func joinIPv6Group(fd *netFD, ifi *Interface, ip IP) error { 196 mreq := &syscall.IPv6Mreq{} 197 copy(mreq.Multiaddr[:], ip) 198 if ifi != nil { 199 mreq.Interface = uint32(ifi.Index) 200 } 201 if err := fd.incref(false); err != nil { 202 return err 203 } 204 defer fd.decref() 205 return os.NewSyscallError("setsockopt", syscall.SetsockoptIPv6Mreq(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_JOIN_GROUP, mreq)) 206 } 207 208 func leaveIPv6Group(fd *netFD, ifi *Interface, ip IP) error { 209 mreq := &syscall.IPv6Mreq{} 210 copy(mreq.Multiaddr[:], ip) 211 if ifi != nil { 212 mreq.Interface = uint32(ifi.Index) 213 } 214 if err := fd.incref(false); err != nil { 215 return err 216 } 217 defer fd.decref() 218 return os.NewSyscallError("setsockopt", syscall.SetsockoptIPv6Mreq(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_LEAVE_GROUP, mreq)) 219 }