The stability level is "Committed" and the release binding is "patch/micro." We're tip-toeing around Linux compatibility and some ugly Linux kernel hackery, so please read carefully. Currently Solaris does not provide a mechanism to set the IP source address for UDP packets on AF_INET (IPv4) sockets. This is a hazard for implementors of UDP based services on Solaris, as it's substantially difficult to get RFC 1123 compliant behavior correct, and many applications (including those shipped with Solaris) fail to do so. See CR 4773220 for details. This project implements such a feature in Solaris The following IPPROTO_IP boolean option may be set or cleared with setsockopt() or retrieved with getsockopt(): IP_RECVPKTINFO Enable/disable receipt of the index of the interface the packet arrived on, the local address that was matched for reception, and the inbound packet's actual destination address. Takes boolean as the parameter. Returns struct in_pktinfo as ancillary data. The following IPPROTO_IP option is only supported as an ancillary data option for sendmsg(3XNET) system call: IP_PKTINFO Set the source address and/or transmit interface of the packet(s). Takes a struct in_pktinfo as the parameter. The symbols and structure are defined as (note the duplicated constant; explained below): /* * New IP source address options */ #define IP_PKTINFO 0x1a /* source address info*/ #define IP_RCVPKTINFO 0x1a /* receive pkt info */ struct in_pktinfo { unsigned int ipi_ifindex; /* send/recv interface index */ struct in_addr ipi_spec_dst; /* src address matched */ struct in_addr ipi_addr; /* src/dst header IP address */ }; When passed in (on transmit) via ancillary data with IP_PKTINFO, ipi_spec_dst is used as the source address and ipi_ifindex is used as the interface index to send the packet out. Differences between Solaris and Linux: This implementation is not completely compatible with the Linux implementation of IP_PKTINFO. However it is compatible with the IPV6_PKTINFO options as described in RFC 3542 for UDP and Raw Sockets. The semantics and behavior of IP_PKTINFO in Linux are not well documented and our efforts to reverse engineer it produced varying results. However we believe in normal cases this implementation will work exactly like the Linux implementation. In particular, Linux uses the setsockopt/getsockopt IP_PKTINFO symbol with two different argument lengths: either 1-4 bytes for boolean, or sizeof (struct in_pktinfo) for the sticky option. We use only the boolean variant, and we duplicate the constant value so that setting IP_PKTINFO trivially has the same effect as setting IP_RECVPKTINFO. - No known Linux application uses the sticky variant of IP_PKTINFO; all that we have been able to locate use IP_PKTINFO as a boolean socket option to enable the ancillary data. For that reason, we expect that nearly all existing Linux applications will port over to Solaris without modification. - The IP_RECVPKTINFO symbol is provided to keep parity with the existing Solaris naming practices. Any Linux application that might use the sticky form in the future will fail this call with EINVAL. If a sticky variant is required in the future, we will revisit using the length hack that Linux uses or create a new symbol. Other things not implemented (but that might have been expected): We will not be extending the existing IPV6_PKTINFO feature to cover IPv4 packets using IPv4-mapped addresses. There are many things that just don't work with IPv4-mapped addresses (such as multicast), that render this old transition mechanism unsuitable for anything but the most trivial of stand-alone services. Thus, we will instead update the documentation to let customers know that they should open multiple sockets (using the IPV6_V6ONLY option) instead, and use inetd's built-in multiple-socket support when possible, and should not rely on robust v4mapped extensions. As stated above sticky option is not supported. Behavior Details: IP_XMIT_IF and IP_DONTFAILOVER_IF options take precedence over IF index passed in IP_PKTINFO. The source address specified on output, if not INADDR_ANY, must be a local host address on an "up" interface. No check is made if another process is bound to that . This socket option does not render the socket actually bound for reception of inbound packets. Note that this is consistent with the way the existing IPv6 option works. EADDRNOTAVAIL is returned if a non-INADDR_ANY address that is not local address is passed in. EINVAL is returned if the index passed in is non-zero and does not correspond to a valid interface. When a non-zero interface index is given along with an all-zero (INADDR_ANY) source address, the packet source address is set to the bound address on the socket or, if that is unset, to one of the addresses hosted on the given physical interface, using the existing source address selection logic to choose among them. When a zero interface index is given along with a non-zero source address, the packet source address is as given in the ancillary data. The output interface will be chosen in the usual manner based on the destination address. Currently Solaris has a consolidation private structure called in_pktinfo that ip uses internally to pass interface information to upper layers. This structure will be renamed to ip_pktinfo.