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