dgramopt.go (7718B)
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 true, 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 }