github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/ipv4/dgramopt.go (about)

     1  // Copyright 2012 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 ipv4
     6  
     7  import (
     8  	"net"
     9  
    10  	"github.com/Andyfoo/golang/x/net/bpf"
    11  )
    12  
    13  // MulticastTTL returns the time-to-live field value for outgoing
    14  // multicast packets.
    15  func (c *dgramOpt) MulticastTTL() (int, error) {
    16  	if !c.ok() {
    17  		return 0, errInvalidConn
    18  	}
    19  	so, ok := sockOpts[ssoMulticastTTL]
    20  	if !ok {
    21  		return 0, errNotImplemented
    22  	}
    23  	return so.GetInt(c.Conn)
    24  }
    25  
    26  // SetMulticastTTL sets the time-to-live field value for future
    27  // outgoing multicast packets.
    28  func (c *dgramOpt) SetMulticastTTL(ttl int) error {
    29  	if !c.ok() {
    30  		return errInvalidConn
    31  	}
    32  	so, ok := sockOpts[ssoMulticastTTL]
    33  	if !ok {
    34  		return errNotImplemented
    35  	}
    36  	return so.SetInt(c.Conn, ttl)
    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 := netAddrToIP4(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 := netAddrToIP4(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 := netAddrToIP4(group)
   152  	if grp == nil {
   153  		return errMissingAddress
   154  	}
   155  	src := netAddrToIP4(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 := netAddrToIP4(group)
   173  	if grp == nil {
   174  		return errMissingAddress
   175  	}
   176  	src := netAddrToIP4(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 := netAddrToIP4(group)
   195  	if grp == nil {
   196  		return errMissingAddress
   197  	}
   198  	src := netAddrToIP4(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 := netAddrToIP4(group)
   216  	if grp == nil {
   217  		return errMissingAddress
   218  	}
   219  	src := netAddrToIP4(source)
   220  	if src == nil {
   221  		return errMissingAddress
   222  	}
   223  	return so.setSourceGroup(c.Conn, ifi, grp, src)
   224  }
   225  
   226  // ICMPFilter returns an ICMP filter.
   227  // Currently only Linux supports this.
   228  func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
   229  	if !c.ok() {
   230  		return nil, errInvalidConn
   231  	}
   232  	so, ok := sockOpts[ssoICMPFilter]
   233  	if !ok {
   234  		return nil, errNotImplemented
   235  	}
   236  	return so.getICMPFilter(c.Conn)
   237  }
   238  
   239  // SetICMPFilter deploys the ICMP filter.
   240  // Currently only Linux supports this.
   241  func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
   242  	if !c.ok() {
   243  		return errInvalidConn
   244  	}
   245  	so, ok := sockOpts[ssoICMPFilter]
   246  	if !ok {
   247  		return errNotImplemented
   248  	}
   249  	return so.setICMPFilter(c.Conn, f)
   250  }
   251  
   252  // SetBPF attaches a BPF program to the connection.
   253  //
   254  // Only supported on Linux.
   255  func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error {
   256  	if !c.ok() {
   257  		return errInvalidConn
   258  	}
   259  	so, ok := sockOpts[ssoAttachFilter]
   260  	if !ok {
   261  		return errNotImplemented
   262  	}
   263  	return so.setBPF(c.Conn, filter)
   264  }