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