Home | History | Annotate | Download | only in net
      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