Commit d3003bed authored by Mikio Hara's avatar Mikio Hara

go.net/ipv6: implement getsockopt, setsockopt syscalls

This CL implements a part of syscall package that's not included
in Go 1.1 release for not to annoy people who need some package
in go.net sub repository with Go 1.1.

Update golang/go#6548

R=dave, dsymonds, adg
CC=golang-dev
https://golang.org/cl/19940044
parent 6fb7275f
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ipv6
type sysSockoptLen uint32
const (
sysSizeofPacketInfo = 0x14
sysSizeofMulticastReq = 0x14
sysSizeofICMPFilter = 0x20
)
type sysPacketInfo struct {
IP [16]byte
IfIndex uint32
}
type sysMulticastReq struct {
IP [16]byte
IfIndex uint32
}
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build freebsd netbsd openbsd
package ipv6
import (
"net"
"syscall"
)
// RFC 3493 options
const (
// See /usr/include/netinet6/in6.h.
sysSockoptUnicastHopLimit = 0x4
sysSockoptMulticastHopLimit = 0xa
sysSockoptMulticastInterface = 0x9
sysSockoptMulticastLoopback = 0xb
sysSockoptJoinGroup = 0xc
sysSockoptLeaveGroup = 0xd
)
// RFC 3542 options
const (
// See /usr/include/netinet6/in6.h.
sysSockoptReceiveTrafficClass = 0x39
sysSockoptTrafficClass = 0x3d
sysSockoptReceiveHopLimit = 0x25
sysSockoptHopLimit = 0x2f
sysSockoptReceivePacketInfo = 0x24
sysSockoptPacketInfo = 0x2e
sysSockoptReceivePathMTU = 0x2b
sysSockoptPathMTU = 0x2c
sysSockoptNextHop = 0x30
sysSockoptChecksum = 0x1a
// See /usr/include/netinet6/in6.h.
sysSockoptICMPFilter = 0x12
)
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
sa.Len = syscall.SizeofSockaddrInet6
sa.Family = syscall.AF_INET6
copy(sa.Addr[:], ip)
sa.Scope_id = uint32(ifindex)
}
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ipv6
import (
"net"
"syscall"
)
// RFC 2292 options
const (
// See /usr/include/netinet6/in6.h.
sysSockopt2292HopLimit = 0x14
sysSockopt2292PacketInfo = 0x13
sysSockopt2292NextHop = 0x15
)
// RFC 3493 options
const (
// See /usr/include/netinet6/in6.h.
sysSockoptUnicastHopLimit = 0x4
sysSockoptMulticastHopLimit = 0xa
sysSockoptMulticastInterface = 0x9
sysSockoptMulticastLoopback = 0xb
sysSockoptJoinGroup = 0xc
sysSockoptLeaveGroup = 0xd
)
// RFC 3542 options
const (
// See /usr/include/netinet6/in6.h.
sysSockoptReceiveTrafficClass = 0x23
sysSockoptTrafficClass = 0x24
sysSockoptReceiveHopLimit = 0x25
sysSockoptHopLimit = 0x2f
sysSockoptReceivePacketInfo = 0x3d
sysSockoptPacketInfo = 0x2e
sysSockoptReceivePathMTU = 0x2b
sysSockoptPathMTU = 0x2c
sysSockoptNextHop = 0x30
sysSockoptChecksum = 0x1a
// See /usr/include/netinet6/in6.h.
sysSockoptICMPFilter = 0x12
)
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
sa.Len = syscall.SizeofSockaddrInet6
sa.Family = syscall.AF_INET6
copy(sa.Addr[:], ip)
sa.Scope_id = uint32(ifindex)
}
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ipv6
import (
"net"
"syscall"
)
// RFC 3493 options
const (
// See /usr/include/linux/in6.h.
sysSockoptUnicastHopLimit = 0x10
sysSockoptMulticastHopLimit = 0x12
sysSockoptMulticastInterface = 0x11
sysSockoptMulticastLoopback = 0x13
sysSockoptJoinGroup = 0x14
sysSockoptLeaveGroup = 0x15
)
// RFC 3542 options
const (
// See /usr/include/linux/ipv6.h,in6.h.
sysSockoptReceiveTrafficClass = 0x42
sysSockoptTrafficClass = 0x43
sysSockoptReceiveHopLimit = 0x33
sysSockoptHopLimit = 0x34
sysSockoptReceivePacketInfo = 0x31
sysSockoptPacketInfo = 0x32
sysSockoptReceivePathMTU = 0x3c
sysSockoptPathMTU = 0x3d
sysSockoptNextHop = 0x9
sysSockoptChecksum = 0x7
// See /usr/include/linux/icmpv6.h.
sysSockoptICMPFilter = 0x1
)
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
sa.Family = syscall.AF_INET6
copy(sa.Addr[:], ip)
sa.Scope_id = uint32(ifindex)
}
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd linux netbsd openbsd
package ipv6
import "syscall"
const sysSizeofMTUInfo = 0x20
type sysMTUInfo struct {
Addr syscall.RawSockaddrInet6
MTU uint32
}
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ipv6
import (
"net"
"syscall"
)
// RFC 3493 options
const (
// See ws2tcpip.h.
sysSockoptUnicastHopLimit = 0x4
sysSockoptMulticastHopLimit = 0xa
sysSockoptMulticastInterface = 0x9
sysSockoptMulticastLoopback = 0xb
sysSockoptJoinGroup = 0xc
sysSockoptLeaveGroup = 0xd
)
// RFC 3542 options
const (
// See ws2tcpip.h.
sysSockoptPacketInfo = 0x13
)
func setSockaddr(sa *syscall.RawSockaddrInet6, ip net.IP, ifindex int) {
sa.Family = syscall.AF_INET6
copy(sa.Addr[:], ip)
sa.Scope_id = uint32(ifindex)
}
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This code is a duplicate of syscall/syscall_linux_386.go with small
// modifications.
package ipv6
import (
"syscall"
"unsafe"
)
// On x86 Linux, all the socket calls go through an extra indirection,
// I think because the 5-register system call interface can't handle
// the 6-argument calls like sendto and recvfrom. Instead the
// arguments to the underlying system call are the number below and a
// pointer to an array of uintptr. We hide the pointer in the
// socketcall assembly to avoid allocation on every system call.
const (
// See /usr/include/linux/net.h.
_SETSOCKOPT = 14
_GETSOCKOPT = 15
)
var socketcall func(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
func getsockopt(fd int, level int, name int, v uintptr, l *sysSockoptLen) error {
if _, errno := socketcall(_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
return error(errno)
}
return nil
}
func setsockopt(fd int, level int, name int, v uintptr, l uintptr) error {
if _, errno := socketcall(_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), v, l, 0); errno != 0 {
return error(errno)
}
return nil
}
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This code is a duplicate of syscall/syscall_linux_386.s with small
// modifications.
#define SYS_SOCKETCALL 102 // from zsysnum_linux_386.go
// func socketcallnosplit7(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
// Kernel interface gets call sub-number and pointer to a0 for Go 1.1.
TEXT ·socketcallnosplit7(SB),7,$0
CALL runtime·entersyscall(SB)
MOVL $SYS_SOCKETCALL, AX // syscall entry
MOVL 4(SP), BX // socket call number
LEAL 8(SP), CX // pointer to call arguments
MOVL $0, DX
MOVL $0, SI
MOVL $0, DI
CALL *runtime·_vdso(SB)
CMPL AX, $0xfffff001
JLS ok1
MOVL $-1, 32(SP) // n
NEGL AX
MOVL AX, 36(SP) // errno
CALL runtime·exitsyscall(SB)
RET
ok1:
MOVL AX, 32(SP) // n
MOVL $0, 36(SP) // errno
CALL runtime·exitsyscall(SB)
RET
// func socketcallnosplit4(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
// Kernel interface gets call sub-number and pointer to a0 for Go 1.2.
TEXT ·socketcallnosplit4(SB),4,$0-40
CALL runtime·entersyscall(SB)
MOVL $SYS_SOCKETCALL, AX // syscall entry
MOVL 4(SP), BX // socket call number
LEAL 8(SP), CX // pointer to call arguments
MOVL $0, DX
MOVL $0, SI
MOVL $0, DI
CALL *runtime·_vdso(SB)
CMPL AX, $0xfffff001
JLS ok2
MOVL $-1, 32(SP) // n
NEGL AX
MOVL AX, 36(SP) // errno
CALL runtime·exitsyscall(SB)
RET
ok2:
MOVL AX, 32(SP) // n
MOVL $0, 36(SP) // errno
CALL runtime·exitsyscall(SB)
RET
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.2
package ipv6
import "syscall"
func socketcallnosplit4(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
func init() {
socketcall = socketcallnosplit4
}
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.1,!go1.2
package ipv6
import "syscall"
func socketcallnosplit7(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
func init() {
socketcall = socketcallnosplit7
}
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin freebsd linux,amd64 linux,arm netbsd openbsd
package ipv6
import (
"syscall"
"unsafe"
)
func getsockopt(fd int, level, name int, v uintptr, l *sysSockoptLen) error {
if _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
return error(errno)
}
return nil
}
func setsockopt(fd int, level int, name int, v uintptr, l uintptr) error {
if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
return error(errno)
}
return nil
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment