unix: add sockaddr_l2 definitions

The sockaddr_l2 address type is used with AF_BLUETOOTH sockets using the
BTPROTO_L2CAP protocol.

Change-Id: I263cfd3bb5920a8c1187ead6c2e0527276575d9f
Reviewed-on: https://go-review.googlesource.com/89475
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/unix/linux/types.go b/unix/linux/types.go
index 1217fd8..f429c8f 100644
--- a/unix/linux/types.go
+++ b/unix/linux/types.go
@@ -162,7 +162,21 @@
         sa_family_t     hci_family;
         unsigned short  hci_dev;
         unsigned short  hci_channel;
-};;
+};
+
+// copied from /usr/include/bluetooth/bluetooth.h
+#define BDADDR_BREDR           0x00
+#define BDADDR_LE_PUBLIC       0x01
+#define BDADDR_LE_RANDOM       0x02
+
+// copied from /usr/include/bluetooth/l2cap.h
+struct sockaddr_l2 {
+	sa_family_t	l2_family;
+	unsigned short	l2_psm;
+	uint8_t		l2_bdaddr[6];
+	unsigned short	l2_cid;
+	uint8_t		l2_bdaddr_type;
+};
 
 // copied from /usr/include/linux/un.h
 struct my_sockaddr_un {
@@ -310,6 +324,8 @@
 
 type RawSockaddrHCI C.struct_sockaddr_hci
 
+type RawSockaddrL2 C.struct_sockaddr_l2
+
 type RawSockaddrCAN C.struct_sockaddr_can
 
 type RawSockaddrALG C.struct_sockaddr_alg
@@ -358,6 +374,7 @@
 	SizeofSockaddrLinklayer = C.sizeof_struct_sockaddr_ll
 	SizeofSockaddrNetlink   = C.sizeof_struct_sockaddr_nl
 	SizeofSockaddrHCI       = C.sizeof_struct_sockaddr_hci
+	SizeofSockaddrL2        = C.sizeof_struct_sockaddr_l2
 	SizeofSockaddrCAN       = C.sizeof_struct_sockaddr_can
 	SizeofSockaddrALG       = C.sizeof_struct_sockaddr_alg
 	SizeofSockaddrVM        = C.sizeof_struct_sockaddr_vm
@@ -643,3 +660,11 @@
 	_CPU_SETSIZE = C.__CPU_SETSIZE
 	_NCPUBITS    = C.__NCPUBITS
 )
+
+// Bluetooth
+
+const (
+	BDADDR_BREDR     = C.BDADDR_BREDR
+	BDADDR_LE_PUBLIC = C.BDADDR_LE_PUBLIC
+	BDADDR_LE_RANDOM = C.BDADDR_LE_RANDOM
+)
diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go
index 839f1d5..5837999 100644
--- a/unix/syscall_linux.go
+++ b/unix/syscall_linux.go
@@ -475,6 +475,29 @@
 	return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil
 }
 
+type SockaddrL2 struct {
+	PSM      uint16
+	CID      uint16
+	Addr     [6]uint8
+	AddrType uint8
+	raw      RawSockaddrL2
+}
+
+func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	sa.raw.Family = AF_BLUETOOTH
+	psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm))
+	psm[0] = byte(sa.PSM)
+	psm[1] = byte(sa.PSM >> 8)
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i]
+	}
+	cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid))
+	cid[0] = byte(sa.CID)
+	cid[1] = byte(sa.CID >> 8)
+	sa.raw.Bdaddr_type = sa.AddrType
+	return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil
+}
+
 // SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets.
 // The RxID and TxID fields are used for transport protocol addressing in
 // (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with
diff --git a/unix/ztypes_linux_386.go b/unix/ztypes_linux_386.go
index 06a9a5b..7aa206e 100644
--- a/unix/ztypes_linux_386.go
+++ b/unix/ztypes_linux_386.go
@@ -254,6 +254,15 @@
 	Channel uint16
 }
 
+type RawSockaddrL2 struct {
+	Family      uint16
+	Psm         uint16
+	Bdaddr      [6]uint8
+	Cid         uint16
+	Bdaddr_type uint8
+	_           [1]byte
+}
+
 type RawSockaddrCAN struct {
 	Family  uint16
 	_       [2]byte
@@ -406,6 +415,7 @@
 	SizeofSockaddrLinklayer = 0x14
 	SizeofSockaddrNetlink   = 0xc
 	SizeofSockaddrHCI       = 0x6
+	SizeofSockaddrL2        = 0xe
 	SizeofSockaddrCAN       = 0x10
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
@@ -853,3 +863,9 @@
 	_CPU_SETSIZE = 0x400
 	_NCPUBITS    = 0x20
 )
+
+const (
+	BDADDR_BREDR     = 0x0
+	BDADDR_LE_PUBLIC = 0x1
+	BDADDR_LE_RANDOM = 0x2
+)
diff --git a/unix/ztypes_linux_amd64.go b/unix/ztypes_linux_amd64.go
index dec10d3..abb3d89 100644
--- a/unix/ztypes_linux_amd64.go
+++ b/unix/ztypes_linux_amd64.go
@@ -256,6 +256,15 @@
 	Channel uint16
 }
 
+type RawSockaddrL2 struct {
+	Family      uint16
+	Psm         uint16
+	Bdaddr      [6]uint8
+	Cid         uint16
+	Bdaddr_type uint8
+	_           [1]byte
+}
+
 type RawSockaddrCAN struct {
 	Family  uint16
 	_       [2]byte
@@ -410,6 +419,7 @@
 	SizeofSockaddrLinklayer = 0x14
 	SizeofSockaddrNetlink   = 0xc
 	SizeofSockaddrHCI       = 0x6
+	SizeofSockaddrL2        = 0xe
 	SizeofSockaddrCAN       = 0x10
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
@@ -871,3 +881,9 @@
 	_CPU_SETSIZE = 0x400
 	_NCPUBITS    = 0x40
 )
+
+const (
+	BDADDR_BREDR     = 0x0
+	BDADDR_LE_PUBLIC = 0x1
+	BDADDR_LE_RANDOM = 0x2
+)
diff --git a/unix/ztypes_linux_arm.go b/unix/ztypes_linux_arm.go
index f15ae9d..1165417 100644
--- a/unix/ztypes_linux_arm.go
+++ b/unix/ztypes_linux_arm.go
@@ -258,6 +258,15 @@
 	Channel uint16
 }
 
+type RawSockaddrL2 struct {
+	Family      uint16
+	Psm         uint16
+	Bdaddr      [6]uint8
+	Cid         uint16
+	Bdaddr_type uint8
+	_           [1]byte
+}
+
 type RawSockaddrCAN struct {
 	Family  uint16
 	_       [2]byte
@@ -410,6 +419,7 @@
 	SizeofSockaddrLinklayer = 0x14
 	SizeofSockaddrNetlink   = 0xc
 	SizeofSockaddrHCI       = 0x6
+	SizeofSockaddrL2        = 0xe
 	SizeofSockaddrCAN       = 0x10
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
@@ -842,3 +852,9 @@
 	_CPU_SETSIZE = 0x400
 	_NCPUBITS    = 0x20
 )
+
+const (
+	BDADDR_BREDR     = 0x0
+	BDADDR_LE_PUBLIC = 0x1
+	BDADDR_LE_RANDOM = 0x2
+)
diff --git a/unix/ztypes_linux_arm64.go b/unix/ztypes_linux_arm64.go
index adeabb6..0d0de46 100644
--- a/unix/ztypes_linux_arm64.go
+++ b/unix/ztypes_linux_arm64.go
@@ -257,6 +257,15 @@
 	Channel uint16
 }
 
+type RawSockaddrL2 struct {
+	Family      uint16
+	Psm         uint16
+	Bdaddr      [6]uint8
+	Cid         uint16
+	Bdaddr_type uint8
+	_           [1]byte
+}
+
 type RawSockaddrCAN struct {
 	Family  uint16
 	_       [2]byte
@@ -411,6 +420,7 @@
 	SizeofSockaddrLinklayer = 0x14
 	SizeofSockaddrNetlink   = 0xc
 	SizeofSockaddrHCI       = 0x6
+	SizeofSockaddrL2        = 0xe
 	SizeofSockaddrCAN       = 0x10
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
@@ -850,3 +860,9 @@
 	_CPU_SETSIZE = 0x400
 	_NCPUBITS    = 0x40
 )
+
+const (
+	BDADDR_BREDR     = 0x0
+	BDADDR_LE_PUBLIC = 0x1
+	BDADDR_LE_RANDOM = 0x2
+)
diff --git a/unix/ztypes_linux_mips.go b/unix/ztypes_linux_mips.go
index 1f9362e..a9087c5 100644
--- a/unix/ztypes_linux_mips.go
+++ b/unix/ztypes_linux_mips.go
@@ -257,6 +257,15 @@
 	Channel uint16
 }
 
+type RawSockaddrL2 struct {
+	Family      uint16
+	Psm         uint16
+	Bdaddr      [6]uint8
+	Cid         uint16
+	Bdaddr_type uint8
+	_           [1]byte
+}
+
 type RawSockaddrCAN struct {
 	Family  uint16
 	_       [2]byte
@@ -409,6 +418,7 @@
 	SizeofSockaddrLinklayer = 0x14
 	SizeofSockaddrNetlink   = 0xc
 	SizeofSockaddrHCI       = 0x6
+	SizeofSockaddrL2        = 0xe
 	SizeofSockaddrCAN       = 0x10
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
@@ -847,3 +857,9 @@
 	_CPU_SETSIZE = 0x400
 	_NCPUBITS    = 0x20
 )
+
+const (
+	BDADDR_BREDR     = 0x0
+	BDADDR_LE_PUBLIC = 0x1
+	BDADDR_LE_RANDOM = 0x2
+)
diff --git a/unix/ztypes_linux_mips64.go b/unix/ztypes_linux_mips64.go
index 2cf42de..01e8f65 100644
--- a/unix/ztypes_linux_mips64.go
+++ b/unix/ztypes_linux_mips64.go
@@ -257,6 +257,15 @@
 	Channel uint16
 }
 
+type RawSockaddrL2 struct {
+	Family      uint16
+	Psm         uint16
+	Bdaddr      [6]uint8
+	Cid         uint16
+	Bdaddr_type uint8
+	_           [1]byte
+}
+
 type RawSockaddrCAN struct {
 	Family  uint16
 	_       [2]byte
@@ -411,6 +420,7 @@
 	SizeofSockaddrLinklayer = 0x14
 	SizeofSockaddrNetlink   = 0xc
 	SizeofSockaddrHCI       = 0x6
+	SizeofSockaddrL2        = 0xe
 	SizeofSockaddrCAN       = 0x10
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
@@ -852,3 +862,9 @@
 	_CPU_SETSIZE = 0x400
 	_NCPUBITS    = 0x40
 )
+
+const (
+	BDADDR_BREDR     = 0x0
+	BDADDR_LE_PUBLIC = 0x1
+	BDADDR_LE_RANDOM = 0x2
+)
diff --git a/unix/ztypes_linux_mips64le.go b/unix/ztypes_linux_mips64le.go
index 94c7c9d..6f9452d 100644
--- a/unix/ztypes_linux_mips64le.go
+++ b/unix/ztypes_linux_mips64le.go
@@ -257,6 +257,15 @@
 	Channel uint16
 }
 
+type RawSockaddrL2 struct {
+	Family      uint16
+	Psm         uint16
+	Bdaddr      [6]uint8
+	Cid         uint16
+	Bdaddr_type uint8
+	_           [1]byte
+}
+
 type RawSockaddrCAN struct {
 	Family  uint16
 	_       [2]byte
@@ -411,6 +420,7 @@
 	SizeofSockaddrLinklayer = 0x14
 	SizeofSockaddrNetlink   = 0xc
 	SizeofSockaddrHCI       = 0x6
+	SizeofSockaddrL2        = 0xe
 	SizeofSockaddrCAN       = 0x10
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
@@ -852,3 +862,9 @@
 	_CPU_SETSIZE = 0x400
 	_NCPUBITS    = 0x40
 )
+
+const (
+	BDADDR_BREDR     = 0x0
+	BDADDR_LE_PUBLIC = 0x1
+	BDADDR_LE_RANDOM = 0x2
+)
diff --git a/unix/ztypes_linux_mipsle.go b/unix/ztypes_linux_mipsle.go
index 99b95e6..6de721f 100644
--- a/unix/ztypes_linux_mipsle.go
+++ b/unix/ztypes_linux_mipsle.go
@@ -257,6 +257,15 @@
 	Channel uint16
 }
 
+type RawSockaddrL2 struct {
+	Family      uint16
+	Psm         uint16
+	Bdaddr      [6]uint8
+	Cid         uint16
+	Bdaddr_type uint8
+	_           [1]byte
+}
+
 type RawSockaddrCAN struct {
 	Family  uint16
 	_       [2]byte
@@ -409,6 +418,7 @@
 	SizeofSockaddrLinklayer = 0x14
 	SizeofSockaddrNetlink   = 0xc
 	SizeofSockaddrHCI       = 0x6
+	SizeofSockaddrL2        = 0xe
 	SizeofSockaddrCAN       = 0x10
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
@@ -847,3 +857,9 @@
 	_CPU_SETSIZE = 0x400
 	_NCPUBITS    = 0x20
 )
+
+const (
+	BDADDR_BREDR     = 0x0
+	BDADDR_LE_PUBLIC = 0x1
+	BDADDR_LE_RANDOM = 0x2
+)
diff --git a/unix/ztypes_linux_ppc64.go b/unix/ztypes_linux_ppc64.go
index c38458b..cb2701f 100644
--- a/unix/ztypes_linux_ppc64.go
+++ b/unix/ztypes_linux_ppc64.go
@@ -258,6 +258,15 @@
 	Channel uint16
 }
 
+type RawSockaddrL2 struct {
+	Family      uint16
+	Psm         uint16
+	Bdaddr      [6]uint8
+	Cid         uint16
+	Bdaddr_type uint8
+	_           [1]byte
+}
+
 type RawSockaddrCAN struct {
 	Family  uint16
 	_       [2]byte
@@ -412,6 +421,7 @@
 	SizeofSockaddrLinklayer = 0x14
 	SizeofSockaddrNetlink   = 0xc
 	SizeofSockaddrHCI       = 0x6
+	SizeofSockaddrL2        = 0xe
 	SizeofSockaddrCAN       = 0x10
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
@@ -860,3 +870,9 @@
 	_CPU_SETSIZE = 0x400
 	_NCPUBITS    = 0x40
 )
+
+const (
+	BDADDR_BREDR     = 0x0
+	BDADDR_LE_PUBLIC = 0x1
+	BDADDR_LE_RANDOM = 0x2
+)
diff --git a/unix/ztypes_linux_ppc64le.go b/unix/ztypes_linux_ppc64le.go
index 33aa1f5..fa5b15b 100644
--- a/unix/ztypes_linux_ppc64le.go
+++ b/unix/ztypes_linux_ppc64le.go
@@ -258,6 +258,15 @@
 	Channel uint16
 }
 
+type RawSockaddrL2 struct {
+	Family      uint16
+	Psm         uint16
+	Bdaddr      [6]uint8
+	Cid         uint16
+	Bdaddr_type uint8
+	_           [1]byte
+}
+
 type RawSockaddrCAN struct {
 	Family  uint16
 	_       [2]byte
@@ -412,6 +421,7 @@
 	SizeofSockaddrLinklayer = 0x14
 	SizeofSockaddrNetlink   = 0xc
 	SizeofSockaddrHCI       = 0x6
+	SizeofSockaddrL2        = 0xe
 	SizeofSockaddrCAN       = 0x10
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
@@ -860,3 +870,9 @@
 	_CPU_SETSIZE = 0x400
 	_NCPUBITS    = 0x40
 )
+
+const (
+	BDADDR_BREDR     = 0x0
+	BDADDR_LE_PUBLIC = 0x1
+	BDADDR_LE_RANDOM = 0x2
+)
diff --git a/unix/ztypes_linux_s390x.go b/unix/ztypes_linux_s390x.go
index 8f4edcd..64952cb 100644
--- a/unix/ztypes_linux_s390x.go
+++ b/unix/ztypes_linux_s390x.go
@@ -257,6 +257,15 @@
 	Channel uint16
 }
 
+type RawSockaddrL2 struct {
+	Family      uint16
+	Psm         uint16
+	Bdaddr      [6]uint8
+	Cid         uint16
+	Bdaddr_type uint8
+	_           [1]byte
+}
+
 type RawSockaddrCAN struct {
 	Family  uint16
 	_       [2]byte
@@ -411,6 +420,7 @@
 	SizeofSockaddrLinklayer = 0x14
 	SizeofSockaddrNetlink   = 0xc
 	SizeofSockaddrHCI       = 0x6
+	SizeofSockaddrL2        = 0xe
 	SizeofSockaddrCAN       = 0x10
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
@@ -877,3 +887,9 @@
 	_CPU_SETSIZE = 0x400
 	_NCPUBITS    = 0x40
 )
+
+const (
+	BDADDR_BREDR     = 0x0
+	BDADDR_LE_PUBLIC = 0x1
+	BDADDR_LE_RANDOM = 0x2
+)