go.net/ipv4: restructure sticky socket option handling

This CL chops existing sticky socket option handlers and puts them
into platform dependent sticky socket option binding table for
supporting multicast features such as source filtering for any-source
multicast, source-specific multicast.

Also adds tiny syscall shims to help to support solaris, to improve
existing platform support.

LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/140640045
diff --git a/ipv4/dgramopt_posix.go b/ipv4/dgramopt_posix.go
index 874afde..fce881a 100644
--- a/ipv4/dgramopt_posix.go
+++ b/ipv4/dgramopt_posix.go
@@ -21,7 +21,7 @@
 	if err != nil {
 		return 0, err
 	}
-	return ipv4MulticastTTL(fd)
+	return getInt(fd, &sockOpts[ssoMulticastTTL])
 }
 
 // SetMulticastTTL sets the time-to-live field value for future
@@ -34,7 +34,7 @@
 	if err != nil {
 		return err
 	}
-	return setIPv4MulticastTTL(fd, ttl)
+	return setInt(fd, &sockOpts[ssoMulticastTTL], ttl)
 }
 
 // MulticastInterface returns the default interface for multicast
@@ -47,7 +47,7 @@
 	if err != nil {
 		return nil, err
 	}
-	return ipv4MulticastInterface(fd)
+	return getInterface(fd, &sockOpts[ssoMulticastInterface])
 }
 
 // SetMulticastInterface sets the default interface for future
@@ -60,7 +60,7 @@
 	if err != nil {
 		return err
 	}
-	return setIPv4MulticastInterface(fd, ifi)
+	return setInterface(fd, &sockOpts[ssoMulticastInterface], ifi)
 }
 
 // MulticastLoopback reports whether transmitted multicast packets
@@ -73,7 +73,11 @@
 	if err != nil {
 		return false, err
 	}
-	return ipv4MulticastLoopback(fd)
+	on, err := getInt(fd, &sockOpts[ssoMulticastLoopback])
+	if err != nil {
+		return false, err
+	}
+	return on == 1, nil
 }
 
 // SetMulticastLoopback sets whether transmitted multicast packets
@@ -86,7 +90,7 @@
 	if err != nil {
 		return err
 	}
-	return setIPv4MulticastLoopback(fd, on)
+	return setInt(fd, &sockOpts[ssoMulticastLoopback], boolint(on))
 }
 
 // JoinGroup joins the group address group on the interface ifi.
@@ -105,7 +109,7 @@
 	if grp == nil {
 		return errMissingAddress
 	}
-	return joinIPv4Group(fd, ifi, grp)
+	return setGroup(fd, &sockOpts[ssoJoinGroup], ifi, grp)
 }
 
 // LeaveGroup leaves the group address group on the interface ifi.
@@ -121,5 +125,5 @@
 	if grp == nil {
 		return errMissingAddress
 	}
-	return leaveIPv4Group(fd, ifi, grp)
+	return setGroup(fd, &sockOpts[ssoLeaveGroup], ifi, grp)
 }