src/pkg/net/sockoptip.go - The Go Programming Language

Golang

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	}