github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/net/ipv6/dgramopt_posix.go (about)

     1  // Copyright 2013 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 windows
     6  
     7  package ipv6
     8  
     9  import (
    10  	"net"
    11  	"syscall"
    12  )
    13  
    14  // MulticastHopLimit returns the hop limit field value for outgoing
    15  // multicast packets.
    16  func (c *dgramOpt) MulticastHopLimit() (int, error) {
    17  	if !c.ok() {
    18  		return 0, syscall.EINVAL
    19  	}
    20  	fd, err := c.sysfd()
    21  	if err != nil {
    22  		return 0, err
    23  	}
    24  	return getInt(fd, &sockOpts[ssoMulticastHopLimit])
    25  }
    26  
    27  // SetMulticastHopLimit sets the hop limit field value for future
    28  // outgoing multicast packets.
    29  func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error {
    30  	if !c.ok() {
    31  		return syscall.EINVAL
    32  	}
    33  	fd, err := c.sysfd()
    34  	if err != nil {
    35  		return err
    36  	}
    37  	return setInt(fd, &sockOpts[ssoMulticastHopLimit], hoplim)
    38  }
    39  
    40  // MulticastInterface returns the default interface for multicast
    41  // packet transmissions.
    42  func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
    43  	if !c.ok() {
    44  		return nil, syscall.EINVAL
    45  	}
    46  	fd, err := c.sysfd()
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  	return getInterface(fd, &sockOpts[ssoMulticastInterface])
    51  }
    52  
    53  // SetMulticastInterface sets the default interface for future
    54  // multicast packet transmissions.
    55  func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
    56  	if !c.ok() {
    57  		return syscall.EINVAL
    58  	}
    59  	fd, err := c.sysfd()
    60  	if err != nil {
    61  		return err
    62  	}
    63  	return setInterface(fd, &sockOpts[ssoMulticastInterface], ifi)
    64  }
    65  
    66  // MulticastLoopback reports whether transmitted multicast packets
    67  // should be copied and send back to the originator.
    68  func (c *dgramOpt) MulticastLoopback() (bool, error) {
    69  	if !c.ok() {
    70  		return false, syscall.EINVAL
    71  	}
    72  	fd, err := c.sysfd()
    73  	if err != nil {
    74  		return false, err
    75  	}
    76  	on, err := getInt(fd, &sockOpts[ssoMulticastLoopback])
    77  	if err != nil {
    78  		return false, err
    79  	}
    80  	return on == 1, nil
    81  }
    82  
    83  // SetMulticastLoopback sets whether transmitted multicast packets
    84  // should be copied and send back to the originator.
    85  func (c *dgramOpt) SetMulticastLoopback(on bool) error {
    86  	if !c.ok() {
    87  		return syscall.EINVAL
    88  	}
    89  	fd, err := c.sysfd()
    90  	if err != nil {
    91  		return err
    92  	}
    93  	return setInt(fd, &sockOpts[ssoMulticastLoopback], boolint(on))
    94  }
    95  
    96  // JoinGroup joins the group address group on the interface ifi.
    97  // By default all sources that can cast data to group are accepted.
    98  // It's possible to mute and unmute data transmission from a specific
    99  // source by using ExcludeSourceSpecificGroup and
   100  // IncludeSourceSpecificGroup.
   101  // JoinGroup uses the system assigned multicast interface when ifi is
   102  // nil, although this is not recommended because the assignment
   103  // depends on platforms and sometimes it might require routing
   104  // configuration.
   105  func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
   106  	if !c.ok() {
   107  		return syscall.EINVAL
   108  	}
   109  	fd, err := c.sysfd()
   110  	if err != nil {
   111  		return err
   112  	}
   113  	grp := netAddrToIP16(group)
   114  	if grp == nil {
   115  		return errMissingAddress
   116  	}
   117  	return setGroup(fd, &sockOpts[ssoJoinGroup], ifi, grp)
   118  }
   119  
   120  // LeaveGroup leaves the group address group on the interface ifi
   121  // regardless of whether the group is any-source group or
   122  // source-specific group.
   123  func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
   124  	if !c.ok() {
   125  		return syscall.EINVAL
   126  	}
   127  	fd, err := c.sysfd()
   128  	if err != nil {
   129  		return err
   130  	}
   131  	grp := netAddrToIP16(group)
   132  	if grp == nil {
   133  		return errMissingAddress
   134  	}
   135  	return setGroup(fd, &sockOpts[ssoLeaveGroup], ifi, grp)
   136  }
   137  
   138  // JoinSourceSpecificGroup joins the source-specific group comprising
   139  // group and source on the interface ifi.
   140  // JoinSourceSpecificGroup uses the system assigned multicast
   141  // interface when ifi is nil, although this is not recommended because
   142  // the assignment depends on platforms and sometimes it might require
   143  // routing configuration.
   144  func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
   145  	if !c.ok() {
   146  		return syscall.EINVAL
   147  	}
   148  	fd, err := c.sysfd()
   149  	if err != nil {
   150  		return err
   151  	}
   152  	grp := netAddrToIP16(group)
   153  	if grp == nil {
   154  		return errMissingAddress
   155  	}
   156  	src := netAddrToIP16(source)
   157  	if src == nil {
   158  		return errMissingAddress
   159  	}
   160  	return setSourceGroup(fd, &sockOpts[ssoJoinSourceGroup], ifi, grp, src)
   161  }
   162  
   163  // LeaveSourceSpecificGroup leaves the source-specific group on the
   164  // interface ifi.
   165  func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
   166  	if !c.ok() {
   167  		return syscall.EINVAL
   168  	}
   169  	fd, err := c.sysfd()
   170  	if err != nil {
   171  		return err
   172  	}
   173  	grp := netAddrToIP16(group)
   174  	if grp == nil {
   175  		return errMissingAddress
   176  	}
   177  	src := netAddrToIP16(source)
   178  	if src == nil {
   179  		return errMissingAddress
   180  	}
   181  	return setSourceGroup(fd, &sockOpts[ssoLeaveSourceGroup], ifi, grp, src)
   182  }
   183  
   184  // ExcludeSourceSpecificGroup excludes the source-specific group from
   185  // the already joined any-source groups by JoinGroup on the interface
   186  // ifi.
   187  func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
   188  	if !c.ok() {
   189  		return syscall.EINVAL
   190  	}
   191  	fd, err := c.sysfd()
   192  	if err != nil {
   193  		return err
   194  	}
   195  	grp := netAddrToIP16(group)
   196  	if grp == nil {
   197  		return errMissingAddress
   198  	}
   199  	src := netAddrToIP16(source)
   200  	if src == nil {
   201  		return errMissingAddress
   202  	}
   203  	return setSourceGroup(fd, &sockOpts[ssoBlockSourceGroup], ifi, grp, src)
   204  }
   205  
   206  // IncludeSourceSpecificGroup includes the excluded source-specific
   207  // group by ExcludeSourceSpecificGroup again on the interface ifi.
   208  func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
   209  	if !c.ok() {
   210  		return syscall.EINVAL
   211  	}
   212  	fd, err := c.sysfd()
   213  	if err != nil {
   214  		return err
   215  	}
   216  	grp := netAddrToIP16(group)
   217  	if grp == nil {
   218  		return errMissingAddress
   219  	}
   220  	src := netAddrToIP16(source)
   221  	if src == nil {
   222  		return errMissingAddress
   223  	}
   224  	return setSourceGroup(fd, &sockOpts[ssoUnblockSourceGroup], ifi, grp, src)
   225  }
   226  
   227  // Checksum reports whether the kernel will compute, store or verify a
   228  // checksum for both incoming and outgoing packets.  If on is true, it
   229  // returns an offset in bytes into the data of where the checksum
   230  // field is located.
   231  func (c *dgramOpt) Checksum() (on bool, offset int, err error) {
   232  	if !c.ok() {
   233  		return false, 0, syscall.EINVAL
   234  	}
   235  	fd, err := c.sysfd()
   236  	if err != nil {
   237  		return false, 0, err
   238  	}
   239  	offset, err = getInt(fd, &sockOpts[ssoChecksum])
   240  	if err != nil {
   241  		return false, 0, err
   242  	}
   243  	if offset < 0 {
   244  		return false, 0, nil
   245  	}
   246  	return true, offset, nil
   247  }
   248  
   249  // SetChecksum enables the kernel checksum processing.  If on is ture,
   250  // the offset should be an offset in bytes into the data of where the
   251  // checksum field is located.
   252  func (c *dgramOpt) SetChecksum(on bool, offset int) error {
   253  	if !c.ok() {
   254  		return syscall.EINVAL
   255  	}
   256  	fd, err := c.sysfd()
   257  	if err != nil {
   258  		return err
   259  	}
   260  	if !on {
   261  		offset = -1
   262  	}
   263  	return setInt(fd, &sockOpts[ssoChecksum], offset)
   264  }
   265  
   266  // ICMPFilter returns an ICMP filter.
   267  func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
   268  	if !c.ok() {
   269  		return nil, syscall.EINVAL
   270  	}
   271  	fd, err := c.sysfd()
   272  	if err != nil {
   273  		return nil, err
   274  	}
   275  	return getICMPFilter(fd, &sockOpts[ssoICMPFilter])
   276  }
   277  
   278  // SetICMPFilter deploys the ICMP filter.
   279  func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
   280  	if !c.ok() {
   281  		return syscall.EINVAL
   282  	}
   283  	fd, err := c.sysfd()
   284  	if err != nil {
   285  		return err
   286  	}
   287  	return setICMPFilter(fd, &sockOpts[ssoICMPFilter], f)
   288  }