1// Copyright 2009 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 hurd linux netbsd openbsd solaris windows 6 7package net 8 9import ( 10 "internal/bytealg" 11 "runtime" 12 "syscall" 13) 14 15// Boolean to int. 16func boolint(b bool) int { 17 if b { 18 return 1 19 } 20 return 0 21} 22 23func ipv4AddrToInterface(ip IP) (*Interface, error) { 24 ift, err := Interfaces() 25 if err != nil { 26 return nil, err 27 } 28 for _, ifi := range ift { 29 ifat, err := ifi.Addrs() 30 if err != nil { 31 return nil, err 32 } 33 for _, ifa := range ifat { 34 switch v := ifa.(type) { 35 case *IPAddr: 36 if ip.Equal(v.IP) { 37 return &ifi, nil 38 } 39 case *IPNet: 40 if ip.Equal(v.IP) { 41 return &ifi, nil 42 } 43 } 44 } 45 } 46 if ip.Equal(IPv4zero) { 47 return nil, nil 48 } 49 return nil, errNoSuchInterface 50} 51 52func interfaceToIPv4Addr(ifi *Interface) (IP, error) { 53 if ifi == nil { 54 return IPv4zero, nil 55 } 56 ifat, err := ifi.Addrs() 57 if err != nil { 58 return nil, err 59 } 60 for _, ifa := range ifat { 61 switch v := ifa.(type) { 62 case *IPAddr: 63 if v.IP.To4() != nil { 64 return v.IP, nil 65 } 66 case *IPNet: 67 if v.IP.To4() != nil { 68 return v.IP, nil 69 } 70 } 71 } 72 return nil, errNoSuchInterface 73} 74 75func setIPv4MreqToInterface(mreq *syscall.IPMreq, ifi *Interface) error { 76 if ifi == nil { 77 return nil 78 } 79 ifat, err := ifi.Addrs() 80 if err != nil { 81 return err 82 } 83 for _, ifa := range ifat { 84 switch v := ifa.(type) { 85 case *IPAddr: 86 if a := v.IP.To4(); a != nil { 87 copy(mreq.Interface[:], a) 88 goto done 89 } 90 case *IPNet: 91 if a := v.IP.To4(); a != nil { 92 copy(mreq.Interface[:], a) 93 goto done 94 } 95 } 96 } 97done: 98 if bytealg.Equal(mreq.Multiaddr[:], IPv4zero.To4()) { 99 return errNoSuchMulticastInterface 100 } 101 return nil 102} 103 104func setReadBuffer(fd *netFD, bytes int) error { 105 err := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes) 106 runtime.KeepAlive(fd) 107 return wrapSyscallError("setsockopt", err) 108} 109 110func setWriteBuffer(fd *netFD, bytes int) error { 111 err := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes) 112 runtime.KeepAlive(fd) 113 return wrapSyscallError("setsockopt", err) 114} 115 116func setKeepAlive(fd *netFD, keepalive bool) error { 117 err := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive)) 118 runtime.KeepAlive(fd) 119 return wrapSyscallError("setsockopt", err) 120} 121 122func setLinger(fd *netFD, sec int) error { 123 var l syscall.Linger 124 if sec >= 0 { 125 l.Onoff = 1 126 l.Linger = int32(sec) 127 } else { 128 l.Onoff = 0 129 l.Linger = 0 130 } 131 err := fd.pfd.SetsockoptLinger(syscall.SOL_SOCKET, syscall.SO_LINGER, &l) 132 runtime.KeepAlive(fd) 133 return wrapSyscallError("setsockopt", err) 134} 135