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 5package ipv6 6 7import ( 8 "net" 9 10 "golang.org/x/net/bpf" 11) 12 13// MulticastHopLimit returns the hop limit field value for outgoing 14// multicast packets. 15func (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. 28func (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. 41func (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. 54func (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. 67func (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. 84func (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. 104func (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. 122func (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. 143func (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. 164func (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. 186func (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. 207func (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. 230func (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. 251func (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. 266func (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. 278func (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. 292func (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} 302