getsockopt()

Updated: April 19, 2023

Get options associated with a socket

Synopsis:

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

int getsockopt( int s,
                int level,
                int optname,
                void * optval,
                socklen_t * optlen );

Arguments:

s
The file descriptor of the socket that the option is to be applied to, as returned by socket().
level
The protocol layer that the option is to be applied to. In most cases, it's a socket-level option and is indicated by SOL_SOCKET.
optname
The option being queried. For a list of options, see Options,” below.
optval
A pointer to the value of the option. In most cases, the value indicates whether the option is currently turned on (nonzero) or off (zero).

Most socket-level options use an int parameter for optval. Others, such as the SO_LINGER, SO_SNDTIMEO, and SO_RCVTIMEO options, use structures that also let you get data associated with the option.

optlen
A pointer to the length of the value of the option. This argument is a value-result parameter; initialize it to indicate the size of the buffer pointed to by optval.

Library:

libsocket

Use the -l socket option to qcc to link against this library.

Description:

The getsockopt() function gets options associated with a socket.

Manipulating socket options

When manipulating a socket option, you must specify the option's name (optname) and the level (level) at which the option resides.

To manipulate options at the socket-level, specify level as SOL_SOCKET. When manipulating options any other level, the value that you specify for level is represented by the protocol number of the appropriate protocol controlling the option. You can obtain the value in a variety of ways:

Note: The latter two ways might not work if you have customized /etc/protocols.

The optname parameter and any specified options are passed uninterpreted to the appropriate protocol module for interpretation. The <sys/socket.h> header file contains definitions for the socket-level options. Options at other protocol levels vary in format and name.

Note: Since levels (e.g., SOL_SOCKET, IPPROTO_IP and IPPROTO_TCP) and the options within the levels can vary, you need to ensure the proper headers are included for both. For example, when setting TCP_NODELAY:
int on = 1;
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));

the level IPPROTO_TCP is defined in <netinet/in.h>, whereas the TCP_NODELAY option is defined in <netinet/tcp.h>.

Options

This section describes some of the more common options and their corresponding level:

IPPROTO_IP:
IP_ADD_MEMBERSHIP · IP_DROP_MEMBERSHIP · IP_ERRORMTU · IP_HDRINCL · IP_IPSEC_POLICY · IP_IPSEC_POLICY_COMPAT · IP_MULTICAST_IF · IP_MULTICAST_LOOP · IP_MULTICAST_TTL · IP_OPTIONS · IP_PKTINFO · IP_PORTALGO · IP_PORTRANGE · IP_RECVDSTADDR · IP_RECVIF · IP_RECVOPTS · IP_RECVPKTINFO · IP_RECVRETOPTS · IP_RETOPTS · IP_TOS · IP_TTL
IPPROTO_IPV6:
IPV6_CHECKSUM · IPV6_DONTFRAG · IPV6_DSTOPTS · IPV6_FAITH · IPV6_HOPLIMIT · IPV6_HOPOPTS · IPV6_IPSEC_POLICY · IPV6_IPSEC_POLICY_COMPAT · IPV6_JOIN_GROUP · IPV6_LEAVE_GROUP · IPV6_MULTICAST_HOPS · IPV6_MULTICAST_IF · IPV6_MULTICAST_LOOP · IPV6_NEXTHOP · IPV6_PATHMTU · IPV6_PKTINFO · IPV6_PORTALGO · IPV6_PORTRANGE · IPV6_PREFER_TEMPADDR · IPV6_RECVDSTOPTS · IPV6_RECVHOPLIMIT · IPV6_RECVHOPOPTS · IPV6_RECVPATHMTU · IPV6_RECVPKTINFO · IPV6_RECVRTHDR · IPV6_RECVTCLASS · IPV6_RTHDR · IPV6_RTHDRDSTOPTS · IPV6_TCLASS · IPV6_UNICAST_HOPS · IPV6_USE_MIN_MTU · IPV6_V6ONLY
SOL_SOCKET:
SO_ACCEPTCONN · SO_BINDTODEVICE · SO_BROADCAST · SO_DEBUG · SO_DONTROUTE · SO_ERROR · SO_KEEPALIVE · SO_LINGER · SO_OOBINLINE · SO_OVERFLOWED · SO_RCVBUF · SO_SNDBUF · SO_RCVLOWAT · SO_RCVTIMEO · SO_REUSEADDR · SO_REUSEPORT · SO_SNDLOWAT · SO_SNDTIMEO · SO_TIMESTAMP · SO_TS_CLOCK · SO_TXPRIO · SO_TYPE · SO_USELOOPBACK · SO_VLANPRIO
IPPROTO_TCP:
TCP_KEEPALIVE · TCP_NODELAY
SOL_LOCAL:
LOCAL_CREDS
Note: Except where noted, you can examine the state of the option by calling getsockopt(), and set the state by calling setsockopt().

IP_ADD_MEMBERSHIP

level: IPPROTO_IP

Join a multicast group.

See IP_ADD_MEMBERSHIP in IP for more information.

IP_DROP_MEMBERSHIP

level: IPPROTO_IP

Drop a multicast group membership.

See IP_DROP_MEMBERSHIP in IP for more information.

IP_ERRORMTU

level: IPPROTO_IP

Get the maximum transmission unit (MTU) of the last XMIT = EMSGSIZE statement.

IP_HDRINCL

level: IPPROTO_IP

Get or set the custom IP header that's included with your data. You can use it only for raw sockets. For example:

(socket(AF_INET, SOCK_RAW, ...)

IP_IPSEC_POLICY or IP_IPSEC_POLICY_COMPAT

level: IPPROTO_IP

Get or set the IP security policy. For example:

const char *policy = "in ipsec ah/transport//require";
char *buf = ipsec_set_policy(policy, strlen(policy));
setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY, buf, ipsec_get_policylen(buf));

See ipsec_set_policy() for more information.

IP_MULTICAST_IF

level: IPPROTO_IP

Override the outgoing interface from which you want to send the multicast datagrams. The default interface is the primary network interface.

See IP_MULTICAST_IF in IP for more information.

IP_MULTICAST_LOOP

level: IPPROTO_IP

Get or set a boolean integer argument that determines whether a copy of a multicast datagram sent to a group to which the sending host itself belongs (on the outgoing interface) is looped back to the host.

See IP_MULTICAST_LOOP in IP for more information.

IP_MULTICAST_TTL

level: IPPROTO_IP

Get or set the time-to-live (TTL) value for the outgoing multicast datagrams to control the scope of the multicasts.

See IP_MULTICAST_TTL in IP for more information.

IP_OPTIONS

level: IPPROTO_IP

Provide the IP options to be transmitted in the IP header of each outgoing packet or examine the header options on incoming packets.

See IP_OPTIONS in IP for more information.

IP_PKTINFO

level: IPPROTO_IP

Specify whether the output interface or the source IP address of a packet will be provided as ancillary data in the control message of a datagram socket in subsequent recvmsg() or sendmsg() calls. For example:

struct in_pktinfo pktinfo;
getsockopt(s, IPPROTO_IP, IP_PKTINFO, &pktinfo, sizeof(pktinfo));

Note that the in_pktinfo argument is stored in the following structure:

struct in_pktinfo {
   struct in_addr  ipi_addr; /* source/destination address */
   unsigned int ipi_ifindex; /* interface index */
};

Setting ipi_ifindex will cause the primary address of that interface to be used. Setting ipi_addr will directly choose that address.

IP_PORTALGO

level: IPPROTO_IP

Get or set the port selection algorithm (RFC 6056) to select a port. For example:

int algo = PORTALGO_RANDOM_START;
getsockopt(s, IPPROTO_IP, IP_PORTALGO, &algo, sizeof(algo));

The following are the port selection algorithms that you can specify through setsockopt():

PORTALGO_DEFAULT        0xffff
PORTALGO_BSD            0
PORTALGO_RANDOM_START   1
PORTALGO_RANDOM_PICK    2
PORTALGO_HASH           3
PORTALGO_DOUBLEHASH     4
PORTALGO_RANDINC        5

IP_PORTRANGE

level: IPPROTO_IP

Get or set the ephemeral port range to use in order to select a local port number when the port number is unspecified at bind() or connect() for SOCK_DGRAM and SOCK_STREAM sockets. For example:

int range = IP_PORTRANGE_HIGH;
setsockopt(s, IPPROTO_IP, IP_PORTRANGE, &range, sizeof(range));

The following are the port ranges that you can specify through setsockopt():

IP_PORTRANGE_DEFAULT  0	/* default range */
IP_PORTRANGE_HIGH     1	/* same as DEFAULT (exists only for FreeBSD compatibility) */
IP_PORTRANGE_LOW      2	/* use privileged range (IPPORT_RESERVEDMIN to IPPORT_RESERVEDMAX)*/

IP_RECVDSTADDR

level: IPPROTO_IP

Enable this option on a SOCK_DGRAM or SOCK_RAW socket to receive the destination IP address for a UDP datagram from recvmsg().

See IP_RECVDSTADDR in IP for more information.

IP_RECVIF

level: IPPROTO_IP

Enable this option on a SOCK_DGRAM or SOCK_RAW socket to receive a struct sockaddr_dl from recvmsg() corresponding to the interface on which the packet was received.

See IP_RECVIF in IP for more information.

IP_RECVOPTS

level: IPPROTO_IP

Set this option on SOCK_DGRAM or SOCK_RAW sockets to receive all incoming IP options in an IP_OPTIONS control message. The routing header and other options are already filled in for the local host.

IP_RECVPKTINFO

level: IPPROTO_IP

Get or set the destination address and the interface index of the packet. This information is passed in struct in_pktinfo which is the same as for IP_PKTINFO.

IP_RECVRETOPTS

level: IPPROTO_IP

Receive the IP options for the response.

IP_RETOPTS

level: IPPROTO_IP

Get or set all incoming IP options to be received in an IP_OPTIONS control message for SOCK_DGRAM or SOCK_RAW sockets. The routing header and other options are already filled in for the local host. The main difference between IP_RETOPTS and IP_RECVOPTS is that IP_RETOPTS returns raw, unprocessed options.

IP_TOS

level: IPPROTO_IP

Get or set the type-of-service (TOS) field in the IP header for SOCK_STREAM and SOCK_DGRAM sockets.

See IP_TOS in IP for more information.

IP_TTL

level: IPPROTO_IP

Get or set the time-to-live (TTL) field in the IP header for SOCK_STREAM and SOCK_DGRAM sockets.

See IP_TTL in IP for more information.

IPV6_CHECKSUM

level: IPPROTO_IPV6

Get or set the checksum offset into an IPv6 packet for SOCK_RAW sockets. Incoming IPv6 packets will be expected to have a checksum of their data stored at this byte offset. Checksums of outgoing IPv6 packets will be computed and stored at this byte offset by the kernel. This option is disabled by default. A value of -1 also disables this option. Note that the checksum for ICMPv6 sockets cannot be relocated or turned off.

int offset = 2;
getsockopt(s, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset));

See IPV6_CHECKSUM in IPv6 for more information.

IPV6_DONTFRAG

level: IPPROTO_IPV6

Set this option to disable fragmentation for IPv6 packets. When this option is set, fragment headers will not be automatically inserted for UDP raw sockets. Output packets larger than the MTU of the outgoing interface will also be dropped.

IPV6_DSTOPTS

level: IPPROTO_IPV6

Get or set whether the destination options will be provided as ancillary data in subsequent recvmsg() calls. This option is stored in the following structure:

struct ip6_dest {
   uint8_t  ip6d_nxt; /* next header */
   uint8_t  ip6d_len; /* length in units of 8 octets */
/* followed by options */
}__attribute__((__packed__));

See IPV6_DSTOPTS in IPv6 for more information.

IPV6_FAITH

level: IPPROTO_IPV6

Get or set the IN6P_FAITH flag on an IPv6 TCP socket. If IN6P_FAITH is turned on and the packet has matching address/port pairs, the packet will be captured by an IPv6 TCP socket. As a result, the faith interface will let you capture IPv6 TCP traffic to specific destination addresses and perform application-specific address mapping to relay IPv6 TCP to IPv4 TCP. For more information, see faith in the NetBSD documentation.

IPV6_HOPLIMIT

level: IPPROTO_IPV6

Get or set whether an integer containing the hop limit header field of the IPv6 packet is delivered in subsqeuent recvmsg() calls as ancillary data.

See IPV6_HOPLIMIT in IPv6 for more information.

IPV6_HOPOPTS

level: IPPROTO_IPV6

Get or set whether the hop-by-hop options from packets are delivered as ancillary data in subsqeuent recvmsg() calls. For example:

struct ip6_hbh hbh;
getsockopt(s, IPPROTO_IPV6, IPV6_HOPOPTS, &hbh, sizeof(hbh));

Note that the ip6_hbh argument is stored in the following structure:

struct ip6_hbh {
	uint8_t ip6h_nxt;	/* next header */
	uint8_t ip6h_len;	/* length in units of 8 octets */
	/* followed by options */
} __attribute__((__packed__));

See IPV6_HOPOPTS in IPv6 for more information.

IPV6_IPSEC_POLICY or IPV6_IPSEC_POLICY_COMPAT

level: IPPROTO_IPV6

Get or set the IPv6 security policy. For example:

const char *policy = "in ipsec ah/transport//require";
char *buf = ipsec_set_policy(policy, strlen(policy));
setsockopt(s, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf, ipsec_get_policylen(buf));

See ipsec_set_policy() for more information.

IPV6_JOIN_GROUP

level: IPPROTO_IPV6

Join an IPv6 multicast group.

See IPV6_JOIN_GROUP in IPv6 for more information.

IPV6_LEAVE_GROUP

level: IPPROTO_IPV6

Drop an IPv6 multicast membership.

See IPV6_LEAVE_GROUP in IPv6 for more information.

IPV6_MULTICAST_HOPS

level: IPPROTO_IPV6

Use this option to control the scope of an outgoing multicast datagram by setting the hop limit header field.

See IPV6_MULTICAST_HOPS in IPv6 for more information.

IPV6_MULTICAST_IF

level: IPPROTO_IPV6

Override the outgoing interface from which you want to send the multicast datagrams. The default interface is the primary network interface.

See IPV6_MULTICAST_IF in IPv6 for more information.

IPV6_MULTICAST_LOOP

level: IPPROTO_IPV6

Get or set a boolean integer argument that determines whether a copy of a multicast datagram sent to a group to which the sending host itself belongs (on the outgoing interface) is looped back to the host.

See IPV6_MULTICAST_LOOP in IPv6 for more information.

IPV6_NEXTHOP

level: IPPROTO_IPV6

Specify the next hop address for the datagram as a socket address structure.

See IPV6_NEXTHOP in IPv6 for more information.

IPV6_PATHMTU

level: IPPROTO_IPV6

Retrieve the current path MTU for UDP and RAW applications.

IPV6_PKTINFO

level: IPPROTO_IPV6

Get the source or destination IPv6 address and the arriving interface index via struct in6_pktinf on an ancillary data stream.

See IPV6_PKTINFO in IPv6 for more information.

IPV6_PORTALGO

level: IPPROTO_IPV6

Get or set the port selection algorithm (RFC 6056) to select a port. For example:

int algo = PORTALGO_RANDOM_START;
getsockopt(s, IPPROTO_IPV6, IPV6_PORTALGO, &algo, sizeof(algo));

The following are the port selection algorithms that you can specify through setsockopt():

PORTALGO_DEFAULT        0xffff
PORTALGO_BSD            0
PORTALGO_RANDOM_START   1
PORTALGO_RANDOM_PICK    2
PORTALGO_HASH           3
PORTALGO_DOUBLEHASH     4
PORTALGO_RANDINC        5

IPV6_PORTRANGE

level: IPPROTO_IPV6

Set the ephemeral port range to use in order to select a local port number when the port number is unspecified for SOCK_DGRAM and SOCK_STREAM sockets.

The following are the port ranges that you can specify through setsockopt():

IPV6_PORTRANGE_DEFAULT  0	/* default range */
IPV6_PORTRANGE_HIGH	    1   /* high range - request firewall bypass */
IPV6_PORTRANGE_LOW      2   /* low range - vouchsafe security */

See IPV6_PORTRANGE in IPv6 for more information.

IPV6_PREFER_TEMPADDR

level: IPPROTO_IPV6

Allow the temporary addresses for privacy extensions to be the preferred source address of packets sent over the given socket. The following are the arguments for IPV6_PREFER_TEMPADDR defined in <netinet6/ip6_var.h>:

IP6PO_TEMPADDR_SYSTEM    -1   /* follow the system default */
IP6PO_TEMPADDR_NOTPREFER  0   /* not prefer temporary address */
IP6PO_TEMPADDR_PREFER     1   /* prefer temporary address */

IPV6_RECVDSTOPTS

level: IPPROTO_IPV6

Receive the destination options header after the router header. Any received IPv6 destination options are to be returned as ancillary data by recvmsg().

IPV6_RECVHOPLIMIT

level: IPPROTO_IPV6

Receive the hop limit of inbound packets as ancillary data through recvmsg().

IPV6_RECVHOPOPTS

level: IPPROTO_IPV6

Receive the hop-by-hop options header of inbound packets as ancillary data through recvmsg(). This option is off by default. Set it as follows:

const int opt = 1;
setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opt, sizeof(opt));

IPV6_RECVPATHMTU

level: IPPROTO_IPV6

Allow recvmsg() to return the path MTU as ancillary data whenever the path MTU changes. A value of 1 enables this option.

IPV6_RECVPKTINFO

level: IPPROTO_IPV6

Allow recvmsg() to return the destination address and the interface index of a received packet as ancillary data for SOCK_DGRAM and SOCK_RAW sockets.

IPV6_RECVRTHDR

level: IPPROTO_IPV6

Allow recvmsg() to return the routing header of a received packet as ancillary data. This option is off by default.

IPV6_RECVTCLASS

level: IPPROTO_IPV6

Allow recvmsg() to return the received traffic class of an IPv6 packet as ancillary data.

IPV6_RTHDR

level: IPPROTO_IPV6

Get or set whether the routing header messages will be provided as ancillary data in subsequent recvmsg() calls. For example:

struct ip6_rthdr rthdr6;
getsockopt(s, IPPROTO_IPV6, IPV6_RTHDR, &rthdr6, sizeof(rthdr6));

Note that the header is stored in the following structure:

struct ip6_rthdr {
	uint8_t  ip6r_nxt;	/* next header */
	uint8_t  ip6r_len;	/* length in units of 8 octets */
	uint8_t  ip6r_type;	/* routing type */
	uint8_t  ip6r_segleft;	/* segments left */
	/* followed by routing type specific data */
} __attribute__((__packed__));

See IPV6_RTHDR in IPv6 for more information.

IPV6_RTHDRDSTOPTS

level: IPPROTO_IPV6

Receive the destination options before the routing header. This option enables applications to specify the destination options that get examined by all of the IP hosts that appear in the routing header.

IPV6_TCLASS

level: IPPROTO_IPV6

Set the traffic class field for outgoing packets to distinguish between different classes and priorities. Acceptable values range from 0 to 255. The default value is 0.

IPV6_UNICAST_HOPS

level: IPPROTO_IPV6

Get or set the hop limit header field for outgoing unicast packets.

See IPV6_UNICAST_HOPS in IPv6 for more information.

IPV6_USE_MIN_MTU

level: IPPROTO_IPV6

Get or set whether packets will be sent at the minimum IPv6 MTU to avoid frgamentation. A value of 1 for this option sends packets using the minimum MTU and disables path MTU discovery. A value of 0 enables path MTU discovery for all destinations. A value of -1 specifies that path MTU discovery is performed for unicast destinations but the minimum IPv6 MTU is used when sending the packet to multicast destinations.

IPV6_V6ONLY

level: IPPROTO_IPV6

Restrict an AF_INET6 socket to only IPv6 communication.

See IPV6_V6ONLY in IPv6 for more information.

SO_ACCEPTCONN (read-only)

level: SOL_SOCKET

Applies to getsockopt() only.

Indicates whether (nonzero) or not (zero) this socket has been marked to accept connections with listen().

SO_BINDTODEVICE (write-only)

level: SOL_SOCKET

Applies to setsockopt() only.

Allow packets to be sent or received on this specified interface only. If the interface specified conflicts with the parameters of bind(), or with the routing table, an error or undesired behavior may occur.

This option accepts the ifreq structure with the ifr_name member set to the interface name (e.g., en0). You can use this option for UDP, TCP, and RAW sockets.

SO_BROADCAST

level: SOL_SOCKET

Enables (nonzero) or disables (zero) the permission to transmit broadcast messages. You can use this option only for UDP sockets. For example:

(socket(AF_INET, SOCK_DGRAM, ...))

“Broadcast” was a privileged operation in earlier versions of the system.

SO_DEBUG

level: SOL_SOCKET

Enables (nonzero) or disables (zero) the recording of debug information in the underlying protocol modules.

SO_DONTROUTE

level: SOL_SOCKET

Enables (nonzero) or disables (zero) the bypassing of routing tables for outgoing messages. Indicates that outgoing messages should bypass the standard routing facilities. The messages are directed to the appropriate network interface according to the network portion of the destination address.

SO_ERROR (read-only)

level: SOL_SOCKET

Applies to getsockopt() only.

Get any pending error on the socket and clears the error status. You can use it to check for asynchronous errors on connected datagram sockets or for other asynchronous errors.

SO_KEEPALIVE

level: SOL_SOCKET

Enables (nonzero) or disables (zero) the periodic (at least every 2 hours) transmission of messages on a connected socket. Should the connected party fail to respond to these messages, the connection is considered broken, and processes that are using the socket are notified via a SIGPIPE signal when they attempt to send data. See Keepalive timing,” below.

SO_LINGER

level: SOL_SOCKET

Controls the action that's taken when unsent messages are queued on socket when a close() is performed.

If it's enabled and the socket promises reliable delivery of data, the system blocks the process on the close() attempt until it's able to transmit the data or until it decides it can't deliver the information (a timeout period, termed the linger interval, is specified in the setsockopt() call when SO_LINGER is requested).

If it's disabled, the system processes the close() in a way that lets the process continue as quickly as possible.

The struct linger parameter (defined in <sys/socket.h>) specifies the desired state of the option in the l_onoff field and the linger interval in the l_linger field, in seconds. A value of 0 causes a reset on the socket when the application closes the socket.

SO_OOBINLINE

level: SOL_SOCKET

For protocols that support out-of-band data, allows (nonzero) or disallows (zero) out-of-band data to be placed in the normal data input queue as received. The data is accessible using the recv() or read() calls without the MSG_OOB flag. Some protocols always behave as if this option is set.

SO_OVERFLOWED (read-only)

level: SOL_SOCKET

Applies to getsockopt() only.

Gets the number of packets that were dropped on the socket due to a full receive buffer.

SO_RCVBUF and SO_SNDBUF

level: SOL_SOCKET

Gets or sets the normal buffer sizes allocated for output (SO_SNDBUF) and input (SO_RCVBUF) buffers. You can increase the buffer size for high-volume connections, or decrease it to limit the possible backlog of incoming data. The system places an absolute limit on these values and defaults them to at least 16 KB for TCP sockets.

SO_RCVLOWAT

level: SOL_SOCKET

Gets or sets the minimum count for input operations (default is 1). In general, receive calls block until any (nonzero) amount of data is received, and then return with the amount available or the amount requested, whichever is smaller.

If you set the value to be larger than the default, blocking receive calls will wait until they've received the low-water mark value or the requested amount, whichever is smaller. Receive calls may still return less than the low-water mark if: an error occurs, a signal is caught, or if the type of data next in the receive queue differs from that returned.

SO_RCVTIMEO

level: SOL_SOCKET

Gets or sets a timeout value for input operations. It accepts a struct timeval parameter (defined in <sys/time.h>) with the number of seconds and microseconds used to limit waits for input operations to complete.

In the current implementation, this timer is restarted each time additional data is received by the protocol, so the limit is in effect an inactivity timer. If a receive operation has been blocked for this much time without receiving additional data, it returns with a short count or, if no data was received, with the error EWOULDBLOCK.

SO_REUSEADDR

level: SOL_SOCKET

Enables (nonzero) or disables (zero) the reuse of duplicate addresses and port bindings. Indicates that the rules used in validating addresses supplied in a bind() call allows/disallows local addresses to be reused.

SO_REUSEPORT

level: SOL_SOCKET

Enables (nonzero) or disables (zero) duplicate address and port bindings. Complete duplicate bindings by multiple processes are allowed when they all set SO_REUSEPORT before binding the port. This option permits multiple instances of a program to each receive UDP/IP multicast or broadcast datagrams destined for the bound port. See the reuseport_unicast option of io-pkt to see how unicast packets are also received on all sockets bound to the same port.

SO_SNDLOWAT

level: SOL_SOCKET

Gets or sets the minimum count for output operations. In BSD, this count is typically 2048, but it is a calculated value in QNX Neutrino. If you require a specific SO_SNDLOWAT, you must specify the count. Most output operations process all of the data supplied by the call, delivering data to the protocol for transmission and blocking as necessary for flow control. Nonblocking output operations will process as much data as permitted (subject to flow control without blocking), but will process no data if flow control doesn't allow the smaller of the low-water mark value or the entire request to be processed.

A poll() operation that tests the ability to write to a socket returns true only if the low-water mark amount could be processed.

SO_SNDTIMEO

level: SOL_SOCKET

Gets or sets a timeout value for output operations. It accepts a struct timeval parameter (defined in <sys/time.h>) that includes the number of seconds and microseconds that are used to limit waits for output operations to complete. If a send operation has blocked for this much time, it returns with a partial count or with the error EWOULDBLOCK if data weren't sent.

This timer is restarted each time additional data is delivered to the protocol, implying that the limit applies to output portions ranging in size from the low-water mark to the high-water mark for output. Timeouts are restricted to 32 seconds or under.

SO_TIMESTAMP

level: SOL_SOCKET

Enables (nonzero) or disables (zero) the reception of a timestamp with datagrams. If enabled on a SOCK_DGRAM socket, the recvmsg() call returns a timestamp corresponding to when the datagram was received. The msg_control field in the msghdr structure points to a buffer that contains a cmsghdr structure followed by a structure accessible through the CMSG_DATA(msg_control) macro. With the default timestamp format, the cmsghdr fields have the following values:

cmsg_len = sizeof(struct cmsghdr) + sizeof(struct timeval)
cmsg_level = SOL_SOCKET
cmsg_type = SCM_TIMESTAMP

SO_TS_CLOCK

level: SOL_SOCKET

Sets the format of the timestamp. After calling setsockopt() to set SO_TIMESTAMP, you can call this function again and set SO_TS_CLOCK to request a specific timestamp format to be returned by SO_TIMESTAMP. The value for SO_TS_CLOCK can be one of:
SO_TS_REALTIME_MICRO
Provides realtime clock data with microsecond resolution. The msg_control field in the msghdr structure points to a buffer with a receive message type (in cmsg_type) of SCM_TIMESTAMP, and a data portion (in CMSG_DATA(msg_control)) containing a struct timeval.

This is the default timestamp type if SO_TS_CLOCK is not specified; this behavior ensures compatibility with existing applications.

SO_TS_REALTIME
Provides realtime clock data with nanosecond resolution. The msg_control field in the msghdr structure points to a buffer containing two protocol-control related messages.

For the first message, the message type (in cmsg_type) is SCM_REALTIME and the data portion (in CMSG_DATA(msg_control)) contains a struct timespec.

For the second message, the message type is SCM_TIMESTAMP and the data portion contains a struct sock_timestamp_info that indicates the timestamp source.

For the SO_TS_REALTIME format, io-pkt can source the timestamp from either the system software clock or a hardware clock. Preference is given to a hardware clock over the system clock, but a hardware clock timestamp is available only when a network driver supports hardware timestamping and the feature was enabled in the driver's command line.

Currently, only devnp-dwceqos-s32g.so supports this feature.

The timestamp source is indicated in the struct sock_timestamp_info.st_info_flags field. If the source is a hardware clock, the ST_INFO_HW flag is set in this field; if it's the system clock, ST_INFO_HW isn't set. In the first (i.e., the hardware) case, ST_INFO_HW_HPREC is also set, indicating that it's a high-precision timestamp. The high-precision timestamp feature is implemented in hardware and the network driver must support this feature.

SO_TXPRIO

level: SOL_SOCKET

Sets the transmit queue priority on a socket. If you set this priority, then all traffic being sent through this socket carries a packet tag of type PACKET_TAG_TXQ, and the value of this packet tag is the priority value set by setsockopt().

Note: In order to get or set this option, you must have specified the so_txprio_enable option when you started io-pkt. Otherwise getsockopt() and setsockopt() set errno to EOPNOTSUPP.

The range of the transmit queue priority is from 0 through 255. How to interpret a priority value—that is, mapping which priority to which transmit queue—is defined in the network driver code.

Here's some code that sets and gets the SO_TXPRIO option:

unsigned char priority = 1;
setsockopt(sfd, SOL_SOCKET, SO_TXPRIO, &priority, sizeof(priority));

int optlen = sizeof(priority);
getsockopt(sfd, SOL_SOCKET, SO_TXPRIO, &priority, &optlen);

The priority variable must be of type unsigned char or u_char, and only values from 0 through 255 are accepted. If priority is more than one byte long (i.e., optlen > 1), then:

For more information about the transmit queue priority and the effects of setting it, see the entry for io-pkt in the Utilities Reference.

SO_TYPE (read-only)

level: SOL_SOCKET

Applies to getsockopt() only.

Gets the type of the socket (e.g., SOCK_STREAM). This information is useful for servers that inherit sockets on startup.

SO_USELOOPBACK

level: SOL_SOCKET

Enables (nonzero) or disables (zero) the sending process to receive its own routing messages.

SO_VLANPRIO

level: SOL_SOCKET

Sets the VLAN priority, a value between 0 to 7, on a socket. If you create a socket and set SO_VLANPRIO, then all traffic being sent through this socket carries a packet tag of type PACKET_TAG_VLANPRIO, and its value is what you set with setsockopt(). If you create a socket but don't set the SO_VLANPRIO, then there isn't a default VLAN priority value, and traffic being sent through this socket doesn't have a PACKET_TAG_VLANPRIO tag. If you require a default VLAN PCP, don't set it using the SO_VLANPRIO option; instead use ifconfig's vlanprio parameter because it has less impact on io-pkt's performance.

The SO_VLANPRIO option works only when a socket is bound to a VLAN interface. Only a VLAN interface can interpret the PACKET_TAG_VLANPRIO tag and set the value in the PCP field of VLAN tag. If you set SO_VLANPRIO on a socket bound to a non-VLAN interface, the traffic is still expected to be transmitted, but setting the option has no useful effect other than slowing down io-pkt.

The value of the SO_VLANPRIO option must be from 0 through 7, and is stored in the P-bit field of a VLAN tag. The meaning of the P-bit value is defined in IEEE 802.1q.

When a VLAN interface has a per-interface VLAN priority, usually being set by ifconfig's vlanprio parameter, and a socket bound to this VLAN interface has its SO_VLANPRIO option set, the final P-bit value in a packet sent through the socket bears the SO_VLANPRIO value.

Here's an example of setting and getting the SO_VLANPRIO option:

unsigned char vlanprio = 1;
setsockopt(sfd, SOL_SOCKET, SO_VLANPRIO, &vlanprio, sizeof(vlanprio));

int optlen = sizeof(vlanprio);
getsockopt(sfd, SOL_SOCKET, SO_VLANPRIO, &vlanprio, &optlen);

The vlanprio variable must be of type unsigned char or u_char. If it's longer than one byte:

TCP_KEEPALIVE

level: IPPROTO_TCP

Gets or sets the amount of time in seconds between keepalive probes (the default value is 2 hours). It accepts an int with the number of seconds to wait between the keepalive probes. See Keepalive timing,” below.

TCP_NODELAY

level: IPPROTO_TCP

Don't delay sending in order to coalesce packets. Under most circumstances, TCP sends data when it's presented. When outstanding data hasn't yet been acknowledged, TCP gathers small amounts of output to be sent in a single packet once an acknowledgment is received.

Note: For a few clients (such as windowing systems that send a stream of mouse events that receive no replies), this packetization may cause significant delays. Therefore, TCP provides a boolean option, TCP_NODELAY, to defeat this algorithm.

LOCAL_CREDS

level: SOL_LOCAL

Provides a mechanism for the receiver to receive the credentials of a process as a recvmsg() message. The LOCAL_CREDS option may be enabled on a SOCK_DGRAM or a SOCK_STREAM socket. The msg_control field in the msghdr structure points to a buffer that contains a cmsghdr structure, followed by a variable length sockcred structure defined in <sys/socket.h> as follows:

struct sockcred {
uid_t   sc_uid;         /* real user id */
uid_t   sc_euid;        /* effective user id */
gid_t   sc_gid;         /* real group id */
gid_t   sc_egid;        /* effective group id */
int     sc_ngroups;     /* number of supplemental groups */
gid_t   sc_groups[1];   /* variable length */
};

The SOCKCREDSIZE() macro computes the size of the sockcred structure for a specified number of groups. The cmsghdr fields have the following values:

cmsg_len = sizeof(struct cmsghdr) + SOCKCREDSIZE(ngroups)
cmsg_level = SOL_SOCKET
cmsg_type = SCM_CREDS

Keepalive timing

Use the SO_KEEPALIVE option to turn on keepalive probes, and the TCP_KEEPALIVE option to set the amount of idle time before a probe is sent out (the default is 7200 seconds, or two hours).

You can set the number of probes to send out and the interval between probes by using the sysctl() function, which modifies or queries the state of the socket manager. The documentation for the sysctl utility includes information on identifiers related to keepcnt and keepintvl. The default number of unsuccessful probes before the socket is considered broken is 8, and the interval between probes defaults to 75 seconds.

Here's an example of turning on a socket keepalive with a 20-second idle time, then up to 3 probes, 5 seconds apart:

int mib[4];
int on=1, ival;
int tval;

mib[0] = CTL_NET;
mib[1] = AF_INET;
mib[2] = IPPROTO_TCP;
mib[3] = TCPCTL_KEEPCNT;
ival = 3; /* Number of keepalive probe attempts
             (default is 8) */
sysctl(mib, 4, NULL, NULL, &ival, sizeof(ival));

mib[0] = CTL_NET;
mib[1] = AF_INET;
mib[2] = IPPROTO_TCP;
mib[3] = TCPCTL_KEEPINTVL;
ival = 10; /* Half seconds between probe attempts;
              default is 150 (75 sec) */
sysctl(mib, 4, NULL, NULL, &ival, sizeof(ival));

memset(&tval, 0, sizeof(tval));
tval.tv_sec = 20;  /* Seconds of idle time before probing
                      starts (default is 7200) */
setsockopt(fdi, SOL_SOCKET, SO_KEEPALIVE, (void *) &on,
           sizeof(on));
setsockopt(fdi, IPPROTO_TCP, TCP_KEEPALIVE, (void *) &tval,
           sizeof(tval);
Note: Beware that the sysctl() calls above make system-wide changes that persist after the process finishes executing.

Returns:

0
Success.
-1
An error occurred (errno is set).

Errors:

EBADF
Invalid file descriptor s.
EDOM
Value was set out of range.
EFAULT
The address pointed to by optval isn't in a valid part of the process address space.
EINVAL
The option is invalid at the level indicated.
ENOPROTOOPT
The protocol doesn't support the given option.
ENOTSOCK
The file descriptor s doesn't refer to a socket.
EOPNOTSUPP
You tried to get the value of the SO_TXPRIO option, but you didn't specify the so_txprio_enable option when you started io-pkt.

Classification:

POSIX 1003.1

Safety:  
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes