Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
IP6(4)			 BSD Kernel Interfaces Manual			IP6(4)

     ip6 -- Internet Protocol version 6	(IPv6)

     #include <sys/types.h>
     #include <sys/socket.h>
     #include <netinet/in.h>

     socket(AF_INET6, SOCK_RAW,	proto);

     IPv6 is the network layer protocol	used by	the Internet protocol version
     6 family (AF_INET6).  Options may be set at the IPv6 level	when using
     higher-level protocols that are based on IPv6 (such as TCP	and UDP).  It
     may also be accessed through a "raw socket" when developing new proto-
     cols, or special-purpose applications.

     There are several IPv6-level setsockopt(2)/getsockopt(2) options.	They
     are separated into	the basic IPv6 sockets API (defined in RFC2553), and
     the advanced API (defined in RFC2292).  The basic API looks very similar
     to	the API	presented in ip(4).  Advanced API uses ancillary data and can
     handle more complex cases.

     To	specify	some of	socket options,	certain	privilege (i.e.	root privi-
     lege) is required.

   Basic IPv6 sockets API
     IPV6_UNICAST_HOPS may be used to set the hoplimit field in	the IPv6
     header.  As symbol	name suggests, the option controls hoplimit field on
     unicast packets.  If -1 is	specified, the kernel will use a default
     value.  If	a value	of 0 to	255 is specified, the packet will have the
     specified value as	hoplimit.  Other values	are considered invalid,	and
     EINVAL will be returned.  For example:

	   int hlim = 60;		    /* max = 255 */
	   setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hlim, sizeof(hlim));

     IPv6 multicasting is supported only on AF_INET6 sockets of	type
     SOCK_DGRAM	and SOCK_RAW, and only on networks where the interface driver
     supports multicasting.

     The IPV6_MULTICAST_HOPS option changes the	hoplimit for outgoing multi-
     cast datagrams in order to	control	the scope of the multicasts:

	   unsigned int	hlim;	   /* range: 0 to 255, default = 1 */
	   setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hlim, sizeof(hlim));

     Datagrams with a hoplimit of 1 are	not forwarded beyond the local net-
     work.  Multicast datagrams	with a hoplimit	of 0 will not be transmitted
     on	any network, but may be	delivered locally if the sending host belongs
     to	the destination	group and if multicast loopback	has not	been disabled
     on	the sending socket (see	below).	 Multicast datagrams with hoplimit
     greater than 1 may	be forwarded to	other networks if a multicast router
     is	attached to the	local network.

     For hosts with multiple interfaces, each multicast	transmission is	sent
     from the primary network interface.  The IPV6_MULTICAST_IF	option over-
     rides the default for subsequent transmissions from a given socket:

	   unsigned int	outif;
	   outif = if_nametoindex("ne0");
	   setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &outif, sizeof(outif));

     where "outif" is an interface index of the	desired	interface, or 0	to
     specify the default interface.

     If	a multicast datagram is	sent to	a group	to which the sending host it-
     self belongs (on the outgoing interface), a copy of the datagram is, by
     default, looped back by the IPv6 layer for	local delivery.	 The
     IPV6_MULTICAST_LOOP option	gives the sender explicit control over whether
     or	not subsequent datagrams are looped back:

	   u_char loop;	   /* 0	= disable, 1 = enable (default)	*/
	   setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop));

     This option improves performance for applications that may	have no	more
     than one instance on a single host	(such as a router daemon), by elimi-
     nating the	overhead of receiving their own	transmissions.	It should gen-
     erally not	be used	by applications	for which there	may be more than one
     instance on a single host (such as	a conferencing program)	or for which
     the sender	does not belong	to the destination group (such as a time
     querying program).

     A multicast datagram sent with an initial hoplimit	greater	than 1 may be
     delivered to the sending host on a	different interface from that on which
     it	was sent, if the host belongs to the destination group on that other
     interface.	 The loopback control option has no effect on such delivery.

     A host must become	a member of a multicast	group before it	can receive
     datagrams sent to the group.  To join a multicast group, use the
     IPV6_JOIN_GROUP option:

	   struct ipv6_mreq mreq6;
	   setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP,	&mreq6,	sizeof(mreq6));

     where mreq6 is the	following structure:

	   struct ipv6_mreq {
	       struct in6_addr ipv6mr_multiaddr;
	       u_int ipv6mr_interface;

     ipv6mr_interface should be	0 to choose the	default	multicast interface,
     or	the interface index of a particular multicast-capable interface	if the
     host is multihomed.  Membership is	associated with	a single interface;
     programs running on multihomed hosts may need to join the same group on
     more than one interface.

     To	drop a membership, use:

	   struct ipv6_mreq mreq6;
	   setsockopt(s, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq6, sizeof(mreq6));

     where mreq6 contains the same values as used to add the membership.  Mem-
     berships are dropped when the socket is closed or the process exits.

     IPV6_PORTRANGE controls how ephemeral ports are allocated for SOCK_STREAM
     and SOCK_DGRAM sockets.  For example,

	   int range = IPV6_PORTRANGE_LOW;	 /* see	<netinet/in.h> */
	   setsockopt(s, IPPROTO_IPV6, IPV6_PORTRANGE, &range, sizeof(range));

     IPV6_V6ONLY controls behavior of AF_INET6 wildcard	listening socket.  The
     following example sets the	option to 1:

	   int on = 1;
	   setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));

     If	set to 1, AF_INET6 wildcard listening socket will accept IPv6 traffic
     only.  If set to 0, it will accept	IPv4 traffic as	well, as if it was
     from IPv4 mapped address like ::ffff:  Note that if you set it
     this to 0,	IPv4 access control gets much more complicated.	 For example,
     even if you have no listening AF_INET listening socket on port X, you
     will end up accepting IPv4	traffic	by AF_INET6 listening socket on	the
     same port.	 The default value for this flag is copied at socket instanti-
     ation time, from net.inet6.ip6.v6only sysctl(3) variable.	The option af-
     fects TCP and UDP sockets only.

   Advanced IPv6 sockets API
     The advanced IPv6 sockets API lets	userland programs specify or obtain
     details about the IPv6 header and the IPv6	extension headers on packets.
     The advanced API uses ancillary data for passing data from/to the kernel.

     There are setsockopt(2)/getsockopt(2) options to get optional information
     on	incoming packets.  They	are IPV6_PKTINFO, IPV6_HOPLIMIT, IPV6_HOPOPTS,

	   int	on = 1;

	   setsockopt(fd, IPPROTO_IPV6,	IPV6_PKTINFO,  &on, sizeof(on));
	   setsockopt(fd, IPPROTO_IPV6,	IPV6_HOPLIMIT, &on, sizeof(on));
	   setsockopt(fd, IPPROTO_IPV6,	IPV6_HOPOPTS,  &on, sizeof(on));
	   setsockopt(fd, IPPROTO_IPV6,	IPV6_DSTOPTS,  &on, sizeof(on));
	   setsockopt(fd, IPPROTO_IPV6,	IPV6_RTHDR,    &on, sizeof(on));

     When any of these options are enabled, the	corresponding data is returned
     as	control	information by recvmsg(2), as one or more ancillary data ob-

     If	IPV6_PKTINFO is	enabled, the destination IPv6 address and the arriving
     interface index will be available via struct in6_pktinfo on ancillary
     data stream.  You can pick	the structure by checking for an ancillary
     data item with cmsg_level equals to IPPROTO_IPV6, and cmsg_type equals to

     If	IPV6_HOPLIMIT is enabled, hoplimit value on the	packet will be made
     available to the userland program.	 Ancillary data	stream will contain an
     integer data item with cmsg_level equals to IPPROTO_IPV6, and cmsg_type
     equals to IPV6_HOPLIMIT.

     inet6_option_space(3) and friends will help you parse ancillary data
     items for IPV6_HOPOPTS and	IPV6_DSTOPTS.  Similarly, inet6_rthdr_space(3)
     and friends will help you parse ancillary data items for IPV6_RTHDR.

     IPV6_HOPOPTS and IPV6_DSTOPTS may appear multiple times on	an ancillary
     data stream (note that the	behavior is slightly different than the	speci-
     fication).	 Other ancillary data item will	appear no more than once.

     For outgoing direction, you can pass ancillary data items with normal
     payload data, using sendmsg(2).  Ancillary	data items will	be parsed by
     the kernel, and used to construct the IPv6	header and extension headers.
     For the 5 cmsg_level values listed	above, ancillary data format is	the
     same as inbound case.  Additionally, you can specify IPV6_NEXTHOP data
     object.  The IPV6_NEXTHOP ancillary data object specifies the next	hop
     for the datagram as a socket address structure.  In the cmsghdr structure
     containing	this ancillary data, the cmsg_level member will	be
     IPPROTO_IPV6, the cmsg_type member	will be	IPV6_NEXTHOP, and the first
     byte of cmsg_data[] will be the first byte	of the socket address struc-

     If	the socket address structure contains an IPv6 address (e.g., the
     sin6_family member	is AF_INET6), then the node identified by that address
     must be a neighbor	of the sending host.  If that address equals the des-
     tination IPv6 address of the datagram, then this is equivalent to the ex-
     isting SO_DONTROUTE socket	option.

     For applications that do not, or unable to	use sendmsg(2) or recvmsg(2),
     IPV6_PKTOPTIONS socket option is defined.	Setting	the socket option
     specifies any of the optional output fields:

	   setsockopt(fd, IPPROTO_IPV6,	IPV6_PKTOPTIONS, &buf, len);

     The fourth	argument points	to a buffer containing one or more ancillary
     data objects, and the fifth argument is the total length of all these ob-
     jects.  The application fills in this buffer exactly as if	the buffer
     were being	passed to sendmsg(2) as	control	information.

     The options set by	calling	setsockopt(2) for IPV6_PKTOPTIONS are called
     "sticky" options because once set they apply to all packets sent on that
     socket.  The application can call setsockopt(2) again to change all the
     sticky options, or	it can call setsockopt(2) with a length	of 0 to	remove
     all the sticky options for	the socket.

     The corresponding receive option

	   getsockopt(fd, IPPROTO_IPV6,	IPV6_PKTOPTIONS, &buf, &len);

     returns a buffer with one or more ancillary data objects for all the op-
     tional receive information	that the application has previously specified
     that it wants to receive.	The fourth argument points to the buffer that
     is	filled in by the call.	The fifth argument is a	pointer	to a value-re-
     sult integer: when	the function is	called the integer specifies the size
     of	the buffer pointed to by the fourth argument, and on return this inte-
     ger contains the actual number of bytes that were returned.  The applica-
     tion processes this buffer	exactly	as if the buffer were returned by
     recvmsg(2)	as control information.

   Advanced API	and TCP	sockets
     When using	getsockopt(2) with the IPV6_PKTOPTIONS option and a TCP
     socket, only the options from the most recently received segment are re-
     tained and	returned to the	caller,	and only after the socket option has
     been set.	The application	is not allowed to specify ancillary data in a
     call to sendmsg(2)	on a TCP socket, and none of the ancillary data	that
     we	described above	is ever	returned as control information	by recvmsg(2)
     on	a TCP socket.

   Conflict resolution
     In	some cases, there are multiple APIs defined for	manipulating a IPv6
     header field.  A good example is the outgoing interface for multicast
     datagrams:	it can be manipulated by IPV6_MULTICAST_IF in basic API,
     IPV6_PKTINFO in advanced API, and sin6_scope_id field of the socket ad-
     dress passed to sendto(2).

     When conflicting options are given	to the kernel, the kernel will get the
     value in the following preference:	(1) options specified by using ancil-
     lary data,	(2) options specified by a sticky option of the	advanced API,
     (3) options specified by using the	basic API, and lastly (4) options
     specified by a socket address.  Note that the conflict resolution is un-
     defined in	the API	specification and implementation dependent.

   Raw IPv6 Sockets
     Raw IPv6 sockets are connectionless, and are normally used	with the
     sendto(2) and recvfrom(2) calls, though the connect(2) call may also be
     used to fix the destination for future packets (in	which case the read(2)
     or	recv(2)	and write(2) or	send(2)	system calls may be used).

     If	proto is 0, the	default	protocol IPPROTO_RAW is	used for outgoing
     packets, and only incoming	packets	destined for that protocol are re-
     ceived.  If proto is non-zero, that protocol number will be used on out-
     going packets and to filter incoming packets.

     Outgoing packets automatically have an IPv6 header	prepended to them
     (based on the destination address and the protocol	number the socket is
     created with).  Incoming packets are received without IPv6	header nor ex-
     tension headers.

     All data sent via raw sockets MUST	be in network byte order and all data
     received via raw sockets will be in network byte order.  This differs
     from the IPv4 raw sockets,	which did not specify a	byte ordering and typ-
     ically used the host's byte order.

     Another difference	from IPv4 raw sockets is that complete packets (that
     is, IPv6 packets with extension headers) cannot be	read or	written	using
     the IPv6 raw sockets API.	Instead, ancillary data	objects	are used to
     transfer the extension headers, as	described above.  Should an applica-
     tion need access to the complete IPv6 packet, some	other technique, such
     as	the datalink interfaces, such as bpf(4), must be used.

     All fields	in the IPv6 header that	an application might want to change
     (i.e., everything other than the version number) can be modified using
     ancillary data and/or socket options by the application for output.  All
     fields in a received IPv6 header (other than the version number and Next
     Header fields) and	all extension headers are also made available to the
     application as ancillary data on input.  Hence there is no	need for a
     socket option similar to the IPv4 IP_HDRINCL socket option.

     When writing to a raw socket the kernel will automatically	fragment the
     packet if its size	exceeds	the path MTU, inserting	the required fragmen-
     tation headers.  On input the kernel reassembles received fragments, so
     the reader	of a raw socket	never sees any fragment	headers.

     Most IPv4 implementations give special treatment to a raw socket created
     with a third argument to socket(2)	of IPPROTO_RAW,	whose value is nor-
     mally 255.	 We note that this value has no	special	meaning	to an IPv6 raw
     socket (and the IANA currently reserves the value of 255 when used	as a
     next-header field).

     For ICMPv6	raw sockets, the kernel	will calculate and insert the ICMPv6
     checksum for since	this checksum is mandatory.

     For other raw IPv6	sockets	(that is, for raw IPv6 sockets created with a
     third argument other than IPPROTO_ICMPV6),	the application	must set the
     new IPV6_CHECKSUM socket option to	have the kernel	(1) compute and	store
     a pseudo header checksum for output, and (2) verify the received pseudo
     header checksum on	input, discarding the packet if	the checksum is	in er-
     ror.  This	option prevents	applications from having to perform source ad-
     dress selection on	the packets they send.	The checksum will incorporate
     the IPv6 pseudo-header, defined in	Section	8.1 of RFC2460.	 This new
     socket option also	specifies an integer offset into the user data of
     where the checksum	is located.

	   int offset =	2;
	   setsockopt(fd, IPPROTO_IPV6,	IPV6_CHECKSUM, &offset,	sizeof(offset));

     By	default, this socket option is disabled.  Setting the offset to	-1
     also disables the option.	By disabled we mean (1)	the kernel will	not
     calculate and store a checksum for	outgoing packets, and (2) the kernel
     will not verify a checksum	for received packets.

     Note: Since the checksum is always	calculated by the kernel for an	ICMPv6
     socket, applications are not able to generate ICMPv6 packets with incor-
     rect checksums (presumably	for testing purposes) using this API.

     A socket operation	may fail with one of the following errors returned:

     [EISCONN]		when trying to establish a connection on a socket
			which already has one, or when trying to send a	data-
			gram with the destination address specified and	the
			socket is already connected;

     [ENOTCONN]		when trying to send a datagram,	but no destination ad-
			dress is specified, and	the socket hasn't been con-

     [ENOBUFS]		when the system	runs out of memory for an internal
			data structure;

     [EADDRNOTAVAIL]	when an	attempt	is made	to create a socket with	a net-
			work address for which no network interface exists.

     [EACCES]		when an	attempt	is made	to create a raw	IPv6 socket by
			a non-privileged process.

     The following errors specific to IPv6 may occur:

     [EINVAL]	      An unknown socket	option name was	given.

     [EINVAL]	      The ancillary data items were improperly formed, or op-
		      tion name	was unknown.

     getsockopt(2), recv(2), send(2), setsockopt(2), inet6_option_space(3),
     inet6_rthdr_space(3), icmp6(4), inet6(4), intro(4)

     W.	Stevens	and M. Thomas, Advanced	Sockets	API for	IPv6, RFC, 2292,
     February 1998.

     S.	Deering	and R. Hinden, Internet	Protocol, Version 6 (IPv6)
     Specification, RFC, 2460, December	1998.

     R.	Gilligan, S. Thomson, J. Bound,	and W. Stevens,	Basic Socket Interface
     Extensions	for IPv6, RFC, 2553, March 1999.

     Most of the socket	options	are defined in RFC2292 and/or RFC2553.

     IPV6_V6ONLY socket	option is defined in draft-ietf-ipngwg-rfc2553bis-03.
     IPV6_PORTRANGE socket option and conflict resolution rule are not defined
     in	the RFCs and should be considered implementation dependent.

     The implementation	is based on KAME stack (which is descendant of WIDE
     hydrangea IPv6 stack kit).

     Part of the document was shamelessly copied from RFC2553 and RFC2292.

     The IPV6_NEXTHOP object/option is not fully implemented as	of writing

BSD				March 13, 2000				   BSD


Want to link to this manual page? Use this URL:

home | help