Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/sys/unix: Sockaddr for AF_IUCV missing #40826

Closed
bluecmd opened this issue Aug 16, 2020 · 3 comments
Closed

x/sys/unix: Sockaddr for AF_IUCV missing #40826

bluecmd opened this issue Aug 16, 2020 · 3 comments

Comments

@bluecmd
Copy link

bluecmd commented Aug 16, 2020

What version of Go are you using (go version)?

$ go version
go version go1.15 linux/s390x

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

N/A

What did you do?

I try to use AF_IUCV with unix.Connect.
However there is no equivalent to sockaddr_iucv, and the interfaces are private so I cannot create one myself.

What did you expect to see?

A SockaddrIUCV structure that allows me to use AF_IUCV.

What did you see instead?

An impossible scenario where I need to use unix.Syscall directly instead.

@gopherbot gopherbot added this to the Unreleased milestone Aug 16, 2020
@bluecmd
Copy link
Author

bluecmd commented Aug 16, 2020

I am thinking maybe something like the following. The C.struct_sockaddr_iucv is 100% untested cargo-cult, no idea if that works, and not clear what I need to do to test it.

diff --git a/unix/linux/types.go b/unix/linux/types.go
index 31a20c7..419ed24 100644
--- a/unix/linux/types.go
+++ b/unix/linux/types.go
@@ -540,6 +540,8 @@ type RawSockaddrL2TPIP C.struct_sockaddr_l2tpip
 
 type RawSockaddrL2TPIP6 C.struct_sockaddr_l2tpip6
 
+type RawSockaddrIUCV C.struct_sockaddr_iucv
+
 type RawSockaddr C.struct_sockaddr
 
 type RawSockaddrAny C.struct_sockaddr_any
@@ -594,6 +596,7 @@ const (
        SizeofSockaddrTIPC      = C.sizeof_struct_sockaddr_tipc
        SizeofSockaddrL2TPIP    = C.sizeof_struct_sockaddr_l2tpip
        SizeofSockaddrL2TPIP6   = C.sizeof_struct_sockaddr_l2tpip6
+       SizeofSockaddrIUCV      = C.sizeof_struct_sockaddr_iucv
        SizeofLinger            = C.sizeof_struct_linger
        SizeofIovec             = C.sizeof_struct_iovec
        SizeofIPMreq            = C.sizeof_struct_ip_mreq
diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go
index 027bcaf..f66c515 100644
--- a/unix/syscall_linux.go
+++ b/unix/syscall_linux.go
@@ -885,6 +885,25 @@ func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) {
        return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil
 }
 
+// SockaddrIUCV implements the Sockaddr interface for AF_IUCV sockets.
+type SockaddrIUCV struct {
+       UserID string
+       Name   string
+       raw    RawSockaddrIUCV
+}
+
+func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) {
+       sa.raw.Family = AF_IUCV
+       for i := 0; i < 8; i++ {
+               sa.raw.Nodeid[i] = ' '
+               sa.raw.User_id[i] = ' '
+               sa.raw.Name[i] = ' '
+       }
+       copy(sa.raw.User_id[:], []byte(sa.UserID))
+       copy(sa.raw.Name[:], []byte(sa.Name))
+       return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil
+}
+
 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
        switch rsa.Addr.Family {
        case AF_NETLINK:
diff --git a/unix/ztypes_linux.go b/unix/ztypes_linux.go
index 83364d7..801f042 100644
--- a/unix/ztypes_linux.go
+++ b/unix/ztypes_linux.go
@@ -310,6 +310,15 @@ type RawSockaddrL2TPIP6 struct {
        Conn_id  uint32
 }
 
+type RawSockaddrIUCV struct {
+       Family   uint16
+       Port     uint16
+       Addr     uint32
+       Nodeid   [8]byte
+       User_id  [8]byte
+       Name     [8]byte
+}
+
 type _Socklen uint32
 
 type Linger struct {
@@ -422,6 +431,7 @@ const (
        SizeofSockaddrTIPC      = 0x10
        SizeofSockaddrL2TPIP    = 0x10
        SizeofSockaddrL2TPIP6   = 0x20
+       SizeofSockaddrIUCV      = 0x20
        SizeofLinger            = 0x8
        SizeofIPMreq            = 0x8
        SizeofIPMreqn           = 0xc

This makes it possible to dial IUCV like this:

package main

import (
  "log"

  "golang.org/x/sys/unix"
)

func main() {
  sock, _ := unix.Socket(unix.AF_IUCV, unix.SOCK_SEQPACKET, 0)
  sa := &unix.SockaddrIUCV{UserID: "TCPIP", Name: "IUCVTEST"}
  if err := unix.Connect(sock, sa); err != nil {
    log.Fatalf("IUCV connect failed: %v", err)
  }
}

@gopherbot
Copy link

Change https://golang.org/cl/248777 mentions this issue: unix: add AF_IUCV and SockaddrIUCV

@bluecmd
Copy link
Author

bluecmd commented Aug 17, 2020

🎉

@golang golang locked and limited conversation to collaborators Aug 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants