From 93218def8b18e66adbdab3eca8ec334700329f1f Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 16 Nov 2018 16:03:55 +0000 Subject: [PATCH] unix: add sockaddr and defines for PPPoE sockets. `sockaddr_pppox` is a packed struct, which godefs doesn't understand. So, I had to do the byte packing by hand instead. Change-Id: Ib92cf43f8ae0729a0af043c4241063911c95e6bf GitHub-Last-Rev: 8982dec099594064d3892f3fa05bb7b5989cec6d GitHub-Pull-Request: golang/sys#23 Reviewed-on: https://go-review.googlesource.com/c/149757 Run-TryBot: Tobias Klauser TryBot-Result: Gobot Gobot Reviewed-by: Tobias Klauser --- unix/linux/types.go | 5 +++ unix/syscall_linux.go | 63 +++++++++++++++++++++++++++++++++++ unix/ztypes_linux_386.go | 3 ++ unix/ztypes_linux_amd64.go | 3 ++ unix/ztypes_linux_arm.go | 3 ++ unix/ztypes_linux_arm64.go | 3 ++ unix/ztypes_linux_mips.go | 3 ++ unix/ztypes_linux_mips64.go | 3 ++ unix/ztypes_linux_mips64le.go | 3 ++ unix/ztypes_linux_mipsle.go | 3 ++ unix/ztypes_linux_ppc64.go | 3 ++ unix/ztypes_linux_ppc64le.go | 3 ++ unix/ztypes_linux_riscv64.go | 3 ++ unix/ztypes_linux_s390x.go | 3 ++ 14 files changed, 104 insertions(+) diff --git a/unix/linux/types.go b/unix/linux/types.go index dca55a5a..273bd469 100644 --- a/unix/linux/types.go +++ b/unix/linux/types.go @@ -48,6 +48,7 @@ package unix #include #include #include +#include #include #include #include @@ -168,6 +169,7 @@ union sockaddr_all { struct sockaddr_un s4; struct sockaddr_ll s5; struct sockaddr_nl s6; + struct sockaddr_pppox s7; }; struct sockaddr_any { @@ -432,6 +434,8 @@ type RawSockaddrVM C.struct_sockaddr_vm type RawSockaddrXDP C.struct_sockaddr_xdp +type RawSockaddrPPPoX [C.sizeof_struct_sockaddr_pppox]byte + type RawSockaddr C.struct_sockaddr type RawSockaddrAny C.struct_sockaddr_any @@ -480,6 +484,7 @@ const ( SizeofSockaddrALG = C.sizeof_struct_sockaddr_alg SizeofSockaddrVM = C.sizeof_struct_sockaddr_vm SizeofSockaddrXDP = C.sizeof_struct_sockaddr_xdp + SizeofSockaddrPPPoX = C.sizeof_struct_sockaddr_pppox 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 84aa8ea0..96ff70dc 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go @@ -12,6 +12,8 @@ package unix import ( + "encoding/binary" + "net" "syscall" "unsafe" ) @@ -710,6 +712,51 @@ func (sa *SockaddrXDP) sockaddr() (unsafe.Pointer, _Socklen, error) { return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil } +// This constant mirrors the #define of PX_PROTO_OE in +// linux/if_pppox.h. We're defining this by hand here instead of +// autogenerating through mkerrors.sh because including +// linux/if_pppox.h causes some declaration conflicts with other +// includes (linux/if_pppox.h includes linux/in.h, which conflicts +// with netinet/in.h). Given that we only need a single zero constant +// out of that file, it's cleaner to just define it by hand here. +const px_proto_oe = 0 + +type SockaddrPPPoE struct { + SID uint16 + Remote net.HardwareAddr + Dev string + raw RawSockaddrPPPoX +} + +func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) { + if len(sa.Remote) != 6 { + return nil, 0, EINVAL + } + if len(sa.Dev) > IFNAMSIZ-1 { + return nil, 0, EINVAL + } + + *(*uint16)(unsafe.Pointer(&sa.raw[0])) = AF_PPPOX + // This next field is in host-endian byte order. We can't use the + // same unsafe pointer cast as above, because this value is not + // 32-bit aligned and some architectures don't allow unaligned + // access. + // + // However, the value of px_proto_oe is 0, so we can use + // encoding/binary helpers to write the bytes without worrying + // about the ordering. + binary.BigEndian.PutUint32(sa.raw[2:6], px_proto_oe) + // This field is deliberately big-endian, unlike the previous + // one. The kernel expects SID to be in network byte order. + binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID) + copy(sa.raw[8:14], sa.Remote) + for i := 14; i < 14+IFNAMSIZ; i++ { + sa.raw[i] = 0 + } + copy(sa.raw[14:], sa.Dev) + return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil +} + func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { switch rsa.Addr.Family { case AF_NETLINK: @@ -820,6 +867,22 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { SharedUmemFD: pp.Shared_umem_fd, } return sa, nil + case AF_PPPOX: + pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa)) + if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe { + return nil, EINVAL + } + sa := &SockaddrPPPoE{ + SID: binary.BigEndian.Uint16(pp[6:8]), + Remote: net.HardwareAddr(pp[8:14]), + } + for i := 14; i < 14+IFNAMSIZ; i++ { + if pp[i] == 0 { + sa.Dev = string(pp[14:i]) + break + } + } + return sa, nil } return nil, EAFNOSUPPORT } diff --git a/unix/ztypes_linux_386.go b/unix/ztypes_linux_386.go index 5f8f0349..f56e164b 100644 --- a/unix/ztypes_linux_386.go +++ b/unix/ztypes_linux_386.go @@ -286,6 +286,8 @@ type RawSockaddrXDP struct { Shared_umem_fd uint32 } +type RawSockaddrPPPoX [0x1e]byte + type RawSockaddr struct { Family uint16 Data [14]int8 @@ -421,6 +423,7 @@ const ( SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 SizeofSockaddrXDP = 0x10 + SizeofSockaddrPPPoX = 0x1e SizeofLinger = 0x8 SizeofIovec = 0x8 SizeofIPMreq = 0x8 diff --git a/unix/ztypes_linux_amd64.go b/unix/ztypes_linux_amd64.go index aa52a439..ac5f636a 100644 --- a/unix/ztypes_linux_amd64.go +++ b/unix/ztypes_linux_amd64.go @@ -288,6 +288,8 @@ type RawSockaddrXDP struct { Shared_umem_fd uint32 } +type RawSockaddrPPPoX [0x1e]byte + type RawSockaddr struct { Family uint16 Data [14]int8 @@ -425,6 +427,7 @@ const ( SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 SizeofSockaddrXDP = 0x10 + SizeofSockaddrPPPoX = 0x1e SizeofLinger = 0x8 SizeofIovec = 0x10 SizeofIPMreq = 0x8 diff --git a/unix/ztypes_linux_arm.go b/unix/ztypes_linux_arm.go index 23c8438b..eb7562da 100644 --- a/unix/ztypes_linux_arm.go +++ b/unix/ztypes_linux_arm.go @@ -289,6 +289,8 @@ type RawSockaddrXDP struct { Shared_umem_fd uint32 } +type RawSockaddrPPPoX [0x1e]byte + type RawSockaddr struct { Family uint16 Data [14]uint8 @@ -424,6 +426,7 @@ const ( SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 SizeofSockaddrXDP = 0x10 + SizeofSockaddrPPPoX = 0x1e SizeofLinger = 0x8 SizeofIovec = 0x8 SizeofIPMreq = 0x8 diff --git a/unix/ztypes_linux_arm64.go b/unix/ztypes_linux_arm64.go index d7a993e2..3c4fb88d 100644 --- a/unix/ztypes_linux_arm64.go +++ b/unix/ztypes_linux_arm64.go @@ -289,6 +289,8 @@ type RawSockaddrXDP struct { Shared_umem_fd uint32 } +type RawSockaddrPPPoX [0x1e]byte + type RawSockaddr struct { Family uint16 Data [14]int8 @@ -426,6 +428,7 @@ const ( SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 SizeofSockaddrXDP = 0x10 + SizeofSockaddrPPPoX = 0x1e SizeofLinger = 0x8 SizeofIovec = 0x10 SizeofIPMreq = 0x8 diff --git a/unix/ztypes_linux_mips.go b/unix/ztypes_linux_mips.go index b8c3d0a4..647e40a7 100644 --- a/unix/ztypes_linux_mips.go +++ b/unix/ztypes_linux_mips.go @@ -287,6 +287,8 @@ type RawSockaddrXDP struct { Shared_umem_fd uint32 } +type RawSockaddrPPPoX [0x1e]byte + type RawSockaddr struct { Family uint16 Data [14]int8 @@ -422,6 +424,7 @@ const ( SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 SizeofSockaddrXDP = 0x10 + SizeofSockaddrPPPoX = 0x1e SizeofLinger = 0x8 SizeofIovec = 0x8 SizeofIPMreq = 0x8 diff --git a/unix/ztypes_linux_mips64.go b/unix/ztypes_linux_mips64.go index a6f76149..e0159b01 100644 --- a/unix/ztypes_linux_mips64.go +++ b/unix/ztypes_linux_mips64.go @@ -289,6 +289,8 @@ type RawSockaddrXDP struct { Shared_umem_fd uint32 } +type RawSockaddrPPPoX [0x1e]byte + type RawSockaddr struct { Family uint16 Data [14]int8 @@ -426,6 +428,7 @@ const ( SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 SizeofSockaddrXDP = 0x10 + SizeofSockaddrPPPoX = 0x1e SizeofLinger = 0x8 SizeofIovec = 0x10 SizeofIPMreq = 0x8 diff --git a/unix/ztypes_linux_mips64le.go b/unix/ztypes_linux_mips64le.go index 3dd19417..c1a024df 100644 --- a/unix/ztypes_linux_mips64le.go +++ b/unix/ztypes_linux_mips64le.go @@ -289,6 +289,8 @@ type RawSockaddrXDP struct { Shared_umem_fd uint32 } +type RawSockaddrPPPoX [0x1e]byte + type RawSockaddr struct { Family uint16 Data [14]int8 @@ -426,6 +428,7 @@ const ( SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 SizeofSockaddrXDP = 0x10 + SizeofSockaddrPPPoX = 0x1e SizeofLinger = 0x8 SizeofIovec = 0x10 SizeofIPMreq = 0x8 diff --git a/unix/ztypes_linux_mipsle.go b/unix/ztypes_linux_mipsle.go index 210de76c..7e525eb7 100644 --- a/unix/ztypes_linux_mipsle.go +++ b/unix/ztypes_linux_mipsle.go @@ -287,6 +287,8 @@ type RawSockaddrXDP struct { Shared_umem_fd uint32 } +type RawSockaddrPPPoX [0x1e]byte + type RawSockaddr struct { Family uint16 Data [14]int8 @@ -422,6 +424,7 @@ const ( SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 SizeofSockaddrXDP = 0x10 + SizeofSockaddrPPPoX = 0x1e SizeofLinger = 0x8 SizeofIovec = 0x8 SizeofIPMreq = 0x8 diff --git a/unix/ztypes_linux_ppc64.go b/unix/ztypes_linux_ppc64.go index b46d54e3..85ae2954 100644 --- a/unix/ztypes_linux_ppc64.go +++ b/unix/ztypes_linux_ppc64.go @@ -290,6 +290,8 @@ type RawSockaddrXDP struct { Shared_umem_fd uint32 } +type RawSockaddrPPPoX [0x1e]byte + type RawSockaddr struct { Family uint16 Data [14]uint8 @@ -427,6 +429,7 @@ const ( SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 SizeofSockaddrXDP = 0x10 + SizeofSockaddrPPPoX = 0x1e SizeofLinger = 0x8 SizeofIovec = 0x10 SizeofIPMreq = 0x8 diff --git a/unix/ztypes_linux_ppc64le.go b/unix/ztypes_linux_ppc64le.go index 6ee799ce..d0c930a1 100644 --- a/unix/ztypes_linux_ppc64le.go +++ b/unix/ztypes_linux_ppc64le.go @@ -290,6 +290,8 @@ type RawSockaddrXDP struct { Shared_umem_fd uint32 } +type RawSockaddrPPPoX [0x1e]byte + type RawSockaddr struct { Family uint16 Data [14]uint8 @@ -427,6 +429,7 @@ const ( SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 SizeofSockaddrXDP = 0x10 + SizeofSockaddrPPPoX = 0x1e SizeofLinger = 0x8 SizeofIovec = 0x10 SizeofIPMreq = 0x8 diff --git a/unix/ztypes_linux_riscv64.go b/unix/ztypes_linux_riscv64.go index 60ae71e6..c1a20bcd 100644 --- a/unix/ztypes_linux_riscv64.go +++ b/unix/ztypes_linux_riscv64.go @@ -289,6 +289,8 @@ type RawSockaddrXDP struct { Shared_umem_fd uint32 } +type RawSockaddrPPPoX [0x1e]byte + type RawSockaddr struct { Family uint16 Data [14]uint8 @@ -426,6 +428,7 @@ const ( SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 SizeofSockaddrXDP = 0x10 + SizeofSockaddrPPPoX = 0x1e SizeofLinger = 0x8 SizeofIovec = 0x10 SizeofIPMreq = 0x8 diff --git a/unix/ztypes_linux_s390x.go b/unix/ztypes_linux_s390x.go index dea88f7b..3c26ea82 100644 --- a/unix/ztypes_linux_s390x.go +++ b/unix/ztypes_linux_s390x.go @@ -288,6 +288,8 @@ type RawSockaddrXDP struct { Shared_umem_fd uint32 } +type RawSockaddrPPPoX [0x1e]byte + type RawSockaddr struct { Family uint16 Data [14]int8 @@ -425,6 +427,7 @@ const ( SizeofSockaddrALG = 0x58 SizeofSockaddrVM = 0x10 SizeofSockaddrXDP = 0x10 + SizeofSockaddrPPPoX = 0x1e SizeofLinger = 0x8 SizeofIovec = 0x10 SizeofIPMreq = 0x8