unix: add AF_IUCV and SockaddrIUCV

On z series machines the IUCV address family is used to communicate
between parts of the machine and other VMs that may be running.

This adds support for addressing these services using AF_IUCV.

Fixes golang/go#40826

Change-Id: I3aba3beb5cb98d9c548d7abc874ca86fb25c8a52
GitHub-Last-Rev: b964d186b4
GitHub-Pull-Request: golang/sys#76
Reviewed-on: https://go-review.googlesource.com/c/sys/+/248777
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
This commit is contained in:
Christian Svensson
2020-08-16 22:12:57 +00:00
committed by Tobias Klauser
parent 3d37ad5750
commit 3ff754bf58
4 changed files with 87 additions and 0 deletions

View File

@@ -257,6 +257,16 @@ struct my_sockaddr_un {
#endif
};
// copied from /usr/include/netiucv/iucv.h modified with explicit signed chars.
struct sockaddr_iucv {
sa_family_t siucv_family;
unsigned short siucv_port;
unsigned int siucv_addr;
signed char siucv_nodeid[8];
signed char siucv_user_id[8];
signed char siucv_name[8];
};
#ifdef __ARM_EABI__
typedef struct user_regs PtraceRegs;
#elif defined(__aarch64__)
@@ -540,6 +550,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 +606,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

View File

@@ -156,6 +156,18 @@ func Test_anyToSockaddr(t *testing.T) {
Name: "gopher",
},
},
{
name: "AF_IUCV",
rsa: sockaddrIUCVToAny(RawSockaddrIUCV{
Family: AF_IUCV,
User_id: [8]int8{'*', 'M', 'S', 'G', ' ', ' ', ' ', ' '},
Name: [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
}),
sa: &SockaddrIUCV{
UserID: "*MSG ",
Name: " ",
},
},
{
name: "AF_MAX EAFNOSUPPORT",
rsa: &RawSockaddrAny{
@@ -505,3 +517,12 @@ func sockaddrUnixToAny(in RawSockaddrUnix) *RawSockaddrAny {
return &out
}
func sockaddrIUCVToAny(in RawSockaddrIUCV) *RawSockaddrAny {
var out RawSockaddrAny
copy(
(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
(*(*[SizeofSockaddrUnix]byte)(unsafe.Pointer(&in)))[:],
)
return &out
}

View File

@@ -885,6 +885,32 @@ 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
// These are EBCDIC encoded by the kernel, but we still need to pad them
// with blanks. Initializing with blanks allows the caller to feed in either
// a padded or an unpadded string.
for i := 0; i < 8; i++ {
sa.raw.Nodeid[i] = ' '
sa.raw.User_id[i] = ' '
sa.raw.Name[i] = ' '
}
for i, b := range []byte(sa.UserID[:8]) {
sa.raw.User_id[i] = int8(b)
}
for i, b := range []byte(sa.Name[:8]) {
sa.raw.Name[i] = int8(b)
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil
}
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family {
case AF_NETLINK:
@@ -1065,6 +1091,23 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
}
return sa, nil
case AF_IUCV:
pp := (*RawSockaddrIUCV)(unsafe.Pointer(rsa))
var user [8]byte
var name [8]byte
for i := 0; i < 8; i++ {
user[i] = byte(pp.User_id[i])
name[i] = byte(pp.Name[i])
}
sa := &SockaddrIUCV{
UserID: string(user[:]),
Name: string(name[:]),
}
return sa, nil
}
return nil, EAFNOSUPPORT
}

View File

@@ -310,6 +310,15 @@ type RawSockaddrL2TPIP6 struct {
Conn_id uint32
}
type RawSockaddrIUCV struct {
Family uint16
Port uint16
Addr uint32
Nodeid [8]int8
User_id [8]int8
Name [8]int8
}
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