summaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorNikhil Benesch <nikhil.benesch@gmail.com>2020-10-10 00:06:36 +0000
committerIan Lance Taylor <iant@golang.org>2020-10-21 16:57:59 -0700
commit2ab1fc7a322e2582772f0e4ed916508c890175e3 (patch)
treea3c3c4cef165b2ec33f3bd8b5df5d4849fd3316a /libgo
parent3fd5876793ddf882994acafc9c5b28e3be8897bd (diff)
syscall: import upstream code for BSD sockets and sysctls
Import some missing upstream code for BSD sockets and sysctls and adapt it for gccgo. Updates golang/go#38538. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/261137
Diffstat (limited to 'libgo')
-rw-r--r--libgo/go/syscall/route_bsd.go2
-rw-r--r--libgo/go/syscall/socket_bsd.go41
-rw-r--r--libgo/go/syscall/syscall_netbsd.go61
3 files changed, 103 insertions, 1 deletions
diff --git a/libgo/go/syscall/route_bsd.go b/libgo/go/syscall/route_bsd.go
index b364eeaba5d..0c32594783c 100644
--- a/libgo/go/syscall/route_bsd.go
+++ b/libgo/go/syscall/route_bsd.go
@@ -18,7 +18,7 @@ var (
// Round the length of a raw sockaddr up to align it properly.
func rsaAlignOf(salen int) int {
- salign := sizeofPtr
+ salign := int(sizeofPtr)
if darwin64Bit {
// Darwin kernels require 32-bit aligned access to
// routing facilities.
diff --git a/libgo/go/syscall/socket_bsd.go b/libgo/go/syscall/socket_bsd.go
index 40637bc7818..b230a3212e6 100644
--- a/libgo/go/syscall/socket_bsd.go
+++ b/libgo/go/syscall/socket_bsd.go
@@ -13,6 +13,7 @@ import "unsafe"
const SizeofSockaddrInet4 = 16
const SizeofSockaddrInet6 = 28
const SizeofSockaddrUnix = 110
+const SizeofSockaddrDatalink = 20
type RawSockaddrInet4 struct {
Len uint8
@@ -76,6 +77,46 @@ func (sa *RawSockaddrUnix) adjustAbstract(sl Socklen_t) Socklen_t {
return sl
}
+type SockaddrDatalink struct {
+ Len uint8
+ Family uint8
+ Index uint16
+ Type uint8
+ Nlen uint8
+ Alen uint8
+ Slen uint8
+ Data [12]int8
+ raw RawSockaddrDatalink
+}
+
+func (sa *SockaddrDatalink) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
+ if sa.Index == 0 {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Len = sa.Len
+ sa.raw.Family = AF_LINK
+ sa.raw.Index = sa.Index
+ sa.raw.Type = sa.Type
+ sa.raw.Nlen = sa.Nlen
+ sa.raw.Alen = sa.Alen
+ sa.raw.Slen = sa.Slen
+ for i := 0; i < len(sa.raw.Data); i++ {
+ sa.raw.Data[i] = sa.Data[i]
+ }
+ return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), SizeofSockaddrDatalink, nil
+}
+
+type RawSockaddrDatalink struct {
+ Len uint8
+ Family uint8
+ Index uint16
+ Type uint8
+ Nlen uint8
+ Alen uint8
+ Slen uint8
+ Data [12]int8
+}
+
type RawSockaddr struct {
Len uint8
Family uint8
diff --git a/libgo/go/syscall/syscall_netbsd.go b/libgo/go/syscall/syscall_netbsd.go
index c67550a011d..bbc6799e3e6 100644
--- a/libgo/go/syscall/syscall_netbsd.go
+++ b/libgo/go/syscall/syscall_netbsd.go
@@ -17,3 +17,64 @@ func direntReclen(buf []byte) (uint64, bool) {
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
+
+func sysctlNodes(mib []_C_int) (nodes []Sysctlnode, err error) {
+ var olen uintptr
+
+ // Get a list of all sysctl nodes below the given MIB by performing
+ // a sysctl for the given MIB with CTL_QUERY appended.
+ mib = append(mib, CTL_QUERY)
+ qnode := Sysctlnode{Flags: SYSCTL_VERS_1}
+ qp := (*byte)(unsafe.Pointer(&qnode))
+ sz := unsafe.Sizeof(qnode)
+ if err = sysctl(mib, nil, &olen, qp, sz); err != nil {
+ return nil, err
+ }
+
+ // Now that we know the size, get the actual nodes.
+ nodes = make([]Sysctlnode, olen/sz)
+ np := (*byte)(unsafe.Pointer(&nodes[0]))
+ if err = sysctl(mib, np, &olen, qp, sz); err != nil {
+ return nil, err
+ }
+
+ return nodes, nil
+}
+
+func nametomib(name string) (mib []_C_int, err error) {
+ // Split name into components.
+ var parts []string
+ last := 0
+ for i := 0; i < len(name); i++ {
+ if name[i] == '.' {
+ parts = append(parts, name[last:i])
+ last = i + 1
+ }
+ }
+ parts = append(parts, name[last:])
+
+ // Discover the nodes and construct the MIB OID.
+ for partno, part := range parts {
+ nodes, err := sysctlNodes(mib)
+ if err != nil {
+ return nil, err
+ }
+ for _, node := range nodes {
+ n := make([]byte, 0)
+ for i := range node.Name {
+ if node.Name[i] != 0 {
+ n = append(n, byte(node.Name[i]))
+ }
+ }
+ if string(n) == part {
+ mib = append(mib, _C_int(node.Num))
+ break
+ }
+ }
+ if len(mib) != partno+1 {
+ return nil, EINVAL
+ }
+ }
+
+ return mib, nil
+}