dgramopt.go (6773B)
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 "golang.org/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 }