ipv4: add port for aix/ppc64

Change-Id: Ida9aed579c9a33883dadfef094c30a658edce88e
Reviewed-on: https://go-review.googlesource.com/c/net/+/170558
Run-TryBot: Mikio Hara <mikioh.public.networking@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Mikio Hara <mikioh.public.networking@gmail.com>
diff --git a/ipv4/control_bsd.go b/ipv4/control_bsd.go
index 77e7ad5..19845c5 100644
--- a/ipv4/control_bsd.go
+++ b/ipv4/control_bsd.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd netbsd openbsd
+// +build aix darwin dragonfly freebsd netbsd openbsd
 
 package ipv4
 
diff --git a/ipv4/control_stub.go b/ipv4/control_stub.go
index a4bcfad..a0c049d 100644
--- a/ipv4/control_stub.go
+++ b/ipv4/control_stub.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
 
 package ipv4
 
diff --git a/ipv4/control_unix.go b/ipv4/control_unix.go
index e1ae816..b27fa49 100644
--- a/ipv4/control_unix.go
+++ b/ipv4/control_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package ipv4
 
diff --git a/ipv4/defs_aix.go b/ipv4/defs_aix.go
new file mode 100644
index 0000000..0f37211
--- /dev/null
+++ b/ipv4/defs_aix.go
@@ -0,0 +1,39 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// +godefs map struct_in_addr [4]byte /* in_addr */
+
+package ipv4
+
+/*
+#include <netinet/in.h>
+*/
+import "C"
+
+const (
+	sysIP_OPTIONS     = C.IP_OPTIONS
+	sysIP_HDRINCL     = C.IP_HDRINCL
+	sysIP_TOS         = C.IP_TOS
+	sysIP_TTL         = C.IP_TTL
+	sysIP_RECVOPTS    = C.IP_RECVOPTS
+	sysIP_RECVRETOPTS = C.IP_RECVRETOPTS
+	sysIP_RECVDSTADDR = C.IP_RECVDSTADDR
+	sysIP_RETOPTS     = C.IP_RETOPTS
+	// IP_RECVIF is defined on AIX but doesn't work.
+	// IP_RECVINTERFACE must be used instead.
+	sysIP_RECVIF  = C.IP_RECVINTERFACE
+	sysIP_RECVTTL = C.IP_RECVTTL
+
+	sysIP_MULTICAST_IF    = C.IP_MULTICAST_IF
+	sysIP_MULTICAST_TTL   = C.IP_MULTICAST_TTL
+	sysIP_MULTICAST_LOOP  = C.IP_MULTICAST_LOOP
+	sysIP_ADD_MEMBERSHIP  = C.IP_ADD_MEMBERSHIP
+	sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP
+
+	sizeofIPMreq = C.sizeof_struct_ip_mreq
+)
+
+type ipMreq C.struct_ip_mreq
diff --git a/ipv4/doc.go b/ipv4/doc.go
index c324f29..2458349 100644
--- a/ipv4/doc.go
+++ b/ipv4/doc.go
@@ -241,5 +241,4 @@
 // IncludeSourceSpecificGroup may return an error.
 package ipv4 // import "golang.org/x/net/ipv4"
 
-// BUG(mikio): This package is not implemented on AIX, JS, NaCl and
-// Plan 9.
+// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.
diff --git a/ipv4/multicast_test.go b/ipv4/multicast_test.go
index 7271dd0..150e21a 100644
--- a/ipv4/multicast_test.go
+++ b/ipv4/multicast_test.go
@@ -29,7 +29,7 @@
 
 func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "solaris", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "solaris", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	ifi, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
@@ -117,7 +117,7 @@
 
 func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "solaris", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "solaris", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if !nettest.SupportsRawSocket() {
@@ -228,7 +228,7 @@
 
 func TestRawConnReadWriteMulticastICMP(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "solaris", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "solaris", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if testing.Short() {
diff --git a/ipv4/multicastlistener_test.go b/ipv4/multicastlistener_test.go
index 591489e..dc3f199 100644
--- a/ipv4/multicastlistener_test.go
+++ b/ipv4/multicastlistener_test.go
@@ -21,7 +21,7 @@
 
 func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if testing.Short() {
@@ -61,7 +61,7 @@
 
 func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if testing.Short() {
@@ -116,7 +116,7 @@
 
 func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if testing.Short() {
@@ -172,7 +172,7 @@
 
 func TestIPSingleRawConnWithSingleGroupListener(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if testing.Short() {
@@ -217,7 +217,7 @@
 
 func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if testing.Short() {
diff --git a/ipv4/multicastsockopt_test.go b/ipv4/multicastsockopt_test.go
index e9f2c57..234c775 100644
--- a/ipv4/multicastsockopt_test.go
+++ b/ipv4/multicastsockopt_test.go
@@ -26,7 +26,7 @@
 
 func TestPacketConnMulticastSocketOptions(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9":
+	case "fuchsia", "hurd", "js", "nacl", "plan9":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	ifi, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
@@ -66,7 +66,7 @@
 
 func TestRawConnMulticastSocketOptions(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9":
+	case "fuchsia", "hurd", "js", "nacl", "plan9":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if !nettest.SupportsRawSocket() {
diff --git a/ipv4/payload_cmsg.go b/ipv4/payload_cmsg.go
index 0693067..e761466 100644
--- a/ipv4/payload_cmsg.go
+++ b/ipv4/payload_cmsg.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package ipv4
 
diff --git a/ipv4/payload_nocmsg.go b/ipv4/payload_nocmsg.go
index d57f05c..1116256 100644
--- a/ipv4/payload_nocmsg.go
+++ b/ipv4/payload_nocmsg.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
 
 package ipv4
 
diff --git a/ipv4/readwrite_test.go b/ipv4/readwrite_test.go
index 5b8b9d3..bd064d5 100644
--- a/ipv4/readwrite_test.go
+++ b/ipv4/readwrite_test.go
@@ -20,7 +20,7 @@
 
 func BenchmarkReadWriteUnicast(b *testing.B) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		b.Skipf("not supported on %s", runtime.GOOS)
 	}
 
@@ -68,7 +68,7 @@
 
 func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		b.Skipf("not supported on %s", runtime.GOOS)
 	}
 
@@ -219,7 +219,7 @@
 
 func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
@@ -299,7 +299,7 @@
 
 func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 
diff --git a/ipv4/sockopt_posix.go b/ipv4/sockopt_posix.go
index 79ac27f..dea6451 100644
--- a/ipv4/sockopt_posix.go
+++ b/ipv4/sockopt_posix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
 
 package ipv4
 
diff --git a/ipv4/sockopt_stub.go b/ipv4/sockopt_stub.go
index 445d3c2..37d4806 100644
--- a/ipv4/sockopt_stub.go
+++ b/ipv4/sockopt_stub.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
 
 package ipv4
 
diff --git a/ipv4/sys_aix.go b/ipv4/sys_aix.go
new file mode 100644
index 0000000..3d1201e
--- /dev/null
+++ b/ipv4/sys_aix.go
@@ -0,0 +1,38 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Added for go1.11 compatibility
+// +build aix
+
+package ipv4
+
+import (
+	"net"
+	"syscall"
+
+	"golang.org/x/net/internal/iana"
+	"golang.org/x/net/internal/socket"
+)
+
+var (
+	ctlOpts = [ctlMax]ctlOpt{
+		ctlTTL:       {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
+		ctlDst:       {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
+		ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
+	}
+
+	sockOpts = map[int]*sockOpt{
+		ssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+		ssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+		ssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
+		ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
+		ssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 1}},
+		ssoReceiveTTL:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
+		ssoReceiveDst:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
+		ssoReceiveInterface:   {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
+		ssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+		ssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+		ssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+	}
+)
diff --git a/ipv4/sys_asmreq.go b/ipv4/sys_asmreq.go
index 0388cba..c5eaafe 100644
--- a/ipv4/sys_asmreq.go
+++ b/ipv4/sys_asmreq.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd netbsd openbsd solaris windows
 
 package ipv4
 
diff --git a/ipv4/sys_asmreq_stub.go b/ipv4/sys_asmreq_stub.go
index dc82806..6dc339c 100644
--- a/ipv4/sys_asmreq_stub.go
+++ b/ipv4/sys_asmreq_stub.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!windows
 
 package ipv4
 
diff --git a/ipv4/sys_stub.go b/ipv4/sys_stub.go
index 4f07647..b9c85b3 100644
--- a/ipv4/sys_stub.go
+++ b/ipv4/sys_stub.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
 
 package ipv4
 
diff --git a/ipv4/unicast_test.go b/ipv4/unicast_test.go
index a4ddfb7..1c105c7 100644
--- a/ipv4/unicast_test.go
+++ b/ipv4/unicast_test.go
@@ -20,7 +20,7 @@
 
 func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if _, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); err != nil {
@@ -70,7 +70,7 @@
 
 func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if !nettest.SupportsRawSocket() {
@@ -155,7 +155,7 @@
 
 func TestRawConnReadWriteUnicastICMP(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if !nettest.SupportsRawSocket() {
diff --git a/ipv4/unicastsockopt_test.go b/ipv4/unicastsockopt_test.go
index 7ff9acc..7527bc1 100644
--- a/ipv4/unicastsockopt_test.go
+++ b/ipv4/unicastsockopt_test.go
@@ -16,7 +16,7 @@
 
 func TestConnUnicastSocketOptions(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if _, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); err != nil {
@@ -61,7 +61,7 @@
 
 func TestPacketConnUnicastSocketOptions(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if _, err := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback); err != nil {
@@ -86,7 +86,7 @@
 
 func TestRawConnUnicastSocketOptions(t *testing.T) {
 	switch runtime.GOOS {
-	case "aix", "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
+	case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
 		t.Skipf("not supported on %s", runtime.GOOS)
 	}
 	if !nettest.SupportsRawSocket() {
diff --git a/ipv4/zsys_aix_ppc64.go b/ipv4/zsys_aix_ppc64.go
new file mode 100644
index 0000000..c741d5c
--- /dev/null
+++ b/ipv4/zsys_aix_ppc64.go
@@ -0,0 +1,33 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_aix.go
+
+// Added for go1.11 compatibility
+// +build aix
+
+package ipv4
+
+const (
+	sysIP_OPTIONS     = 0x1
+	sysIP_HDRINCL     = 0x2
+	sysIP_TOS         = 0x3
+	sysIP_TTL         = 0x4
+	sysIP_RECVOPTS    = 0x5
+	sysIP_RECVRETOPTS = 0x6
+	sysIP_RECVDSTADDR = 0x7
+	sysIP_RETOPTS     = 0x8
+	sysIP_RECVIF      = 0x20
+	sysIP_RECVTTL     = 0x22
+
+	sysIP_MULTICAST_IF    = 0x9
+	sysIP_MULTICAST_TTL   = 0xa
+	sysIP_MULTICAST_LOOP  = 0xb
+	sysIP_ADD_MEMBERSHIP  = 0xc
+	sysIP_DROP_MEMBERSHIP = 0xd
+
+	sizeofIPMreq = 0x8
+)
+
+type ipMreq struct {
+	Multiaddr [4]byte /* in_addr */
+	Interface [4]byte /* in_addr */
+}