SOCKADDR(3SOCKET) Sockets Library Functions SOCKADDR(3SOCKET)
NAME
sockaddr,
sockaddr_dl,
sockaddr_in,
sockaddr_in6,
sockaddr_ll,
sockaddr_storage,
sockaddr_un - Socket Address Structures
SYNOPSIS
#include <sys/socket.h> struct sockaddr sock;
#include <sys/socket.h> #include <net/if_dl.h> struct sockaddr_dl dl_sock;
#include <sys/socket.h> #include <netinet/in.h> struct sockaddr_in in_sock;
#include <sys/socket.h> #include <netinet/in.h> struct sockaddr_in6 in6_sock;
#include <sys/socket.h> struct sockaddr_ll ll_sock;
#include <sys/socket.h> struct sockaddr_storage storage_sock;
#include <sys/un.h> struct sockaddr_un un_sock;
DESCRIPTION
The
sockaddr family of structures are designed to represent network
addresses for different networking protocols. The structure
struct sockaddr is a generic structure that is used across calls to various
socket library routines (
libsocket(3LIB)) such as
accept(3SOCKET) and
bind(3SOCKET). Applications do not use the
struct sockaddr directly,
but instead cast the appropriate networking family specific
sockaddr structure to a
struct sockaddr *.
Every structure in the
sockaddr family begins with a member of the same
type, the
sa_family_t, though the different structures all have
different names for the member. For example, the structure
struct sockaddr has the following members defined:
sa_family_t sa_family /* address family */
char sa_data[] /* socket address (variable-length data) */
The member
sa_family corresponds to the socket family that's actually
in use. The following table describes the mapping between the address
family and the corresponding socket structure that's used. Note that
both the generic
struct sockaddr and the
struct sockaddr_storage are
not included, because these are both generic structures. More on the
struct sockaddr_storage can be found in the next section.
Socket Structure Address Family struct sockaddr_dl AF_LINK
struct sockaddr_in AF_INET
struct sockaddr_in6 AF_INET6
struct sockaddr_ll AF_PACKET
struct sockaddr_un AF_UNIX
struct sockaddr_storage The
sockaddr_storage structure is a
sockaddr that is not associated
with an address family. Instead, it is large enough to hold the
contents of any of the other
sockaddr structures. It can be used to
embed sufficient storage for a
sockaddr of any type within a larger
structure.
The structure only has a single member defined. While there are other
members that are used to pad out the size of the
struct sockaddr_storage, they are not defined and must not be consumed. The
only valid member is:
sa_family_t ss_family /* address family */
For example,
struct sockaddr_storage is useful when running a service
that accepts traffic over both
IPv4 and
IPv6 where it is common to use
a single socket for both address families. In that case, rather than
guessing whether a
struct sockaddr_in or a
struct sockaddr_in6 is more
appropriate, one can simply use a
struct sockaddr_storage and cast to
the appropriate family-specific structure type based on the value of
the member
ss_family.
struct sockaddr_in The
sockaddr_in is the socket type which is used for for the Internet
Protocol version four (IPv4). It has the following members defined:
sa_family_t sin_family /* address family */
in_port_t sin_port /* IP port */
struct in_addr sin_addr /* IP address */
The member
sin_family must always have the value
AF_INET for
IPv4. The
members
sin_port and
sin_addr describe the IP address and IP port to
use. In the case of a call to
connect(3SOCKET) these represent the
remote IP address and port to which the connection is being made. In
the case of
bind(3SOCKET) these represent the IP address and port on
the local host to which the socket is to be bound. In the case of
accept(3SOCKET) these represent the remote IP address and port of the
machine whose connection was accepted.
The member
sin_port is always stored in
Network Byte Order. On many
systems, this differs from the native host byte order. Applications
should read from the member with the function
ntohs(3C) and write to
the member with the function
htons(3C). The member
sin_addr is the
four byte IPv4 address. It is also stored in network byte order. The
common way to write out the address is to use the function
inet_pton(3C) which converts between a human readable IP address such
as "10.1.2.3" and the corresponding representation.
Example 1 shows how to prepare an IPv4 socket and deal with network
byte-order. See
inet(4P) and
ip(4P) for more information on IPv4,
socket options, etc.
struct sockaddr_in6 The
sockaddr_in6 structure is the
sockaddr for the Internet Protocol
version six (IPv6). Unlike the
struct sockaddr_in, the
struct sockaddr_in6 has additional members beyond those shown here which are
required to be initialized to zero through a function such as
bzero(3C) or
memset(3C). If the entire
struct sockaddr_in6 is not zeroed before
use, applications will experience undefined behavior. The
struct sockaddr_in6 has the following public members:
sa_family_t sin6_family /* address family */
in_port_t sin6_port /* IPv6 port */
struct in6_addr sin6_addr /* IPv6 address */
uint32_t sin6_flowinfo; /* traffic class and flow info */
uint32_t sin6_scope_id; /* interface scope */
The member
sin6_family must always have the value
AF_INET6. The
members
sin6_port and
sin6_addr are the IPv6 equivalents of the
struct sockaddr_in sin_port and
sin_addr. Like their IPv4 counterparts, both
of these members must be in network byte order. The member
sin6_port describes the IPv6 port and should be manipulated with the functions
ntohs(3C) and
htons(3C). The member
sin6_addr describes the 16-byte
IPv6 address. In addition to the function
inet_pton(3C), the header
file <
netinet/in.h> defines many macros for manipulating and testing
IPv6 addresses.
The member
sin6_flowinfo contains the traffic class and flow label
associated with the IPv6 header. The member
sin6_scope_id may contain
an identifier which varies based on the scope of the address in
sin6_addr. Applications do not need to initialize
sin6_scope_id; it
will be populated by the operating system as a result of various
library calls.
Example 2 shows how to prepare an IPv6 socket. For more information on
IPv6, please see
inet6(4P) and
ip6(4P).
struct sockaddr_un The
sockaddr_un structure specifies the address of a socket used to
communicate between processes running on a single system, commonly
known as a
UNIX domain socket. Sockets of this type are identified by
a path in the file system. The
struct sockaddr_un has the following
members:
sa_family_t sun_family /* address family */
char sun_path[108] /* path name */
The member
sun_family must always have the value
AF_UNIX. The member
sun_path is populated with a
NUL terminated array of characters that
specify a file system path. The maximum length of any such path,
including the
NUL terminator, is 108 bytes.
struct sockaddr_dl The
sockaddr_dl structure is used to describe a layer 2 link-level
address. This is used as part of various socket ioctls, such as those
for
arp(4P). The structure has the following members:
ushort_t sdl_family; /* address family */
ushort_t sdl_index; /* if != 0, system interface index */
uchar_t sdl_type; /* interface type */
uchar_t sdl_nlen; /* interface name length */
uchar_t sdl_alen; /* link level address length */
uchar_t sdl_slen; /* link layer selector length */
char sdl_data[244]; /* contains both if name and ll address
The member
sdl_family must always have the value
AF_LINK. When the
member
sdl_index is non-zero this refers to the interface identifier
that corresponds to the
struct sockaddr_dl. This identifier is the
same identifier that's shown by tools like
ifconfig(8) and used in the
SIOC* set of socket ioctls. The member
sdl_type refers to the media
that is used for the socket. The most common case is that the medium
for the interface is Ethernet which has the value
IFT_ETHER. The full
set of types is derived from RFC1573 and recorded in the file
<
net/if_types.h>. The member
sdl_slen describes the length of a
selector, if it exists, for the specified medium. This is used in
protocols such as Trill.
The
sdl_data,
sdl_nlen and
sdl_alen members together describe a
character string containing the interface name and the link-layer
network address. The name starts at the beginning of
sdl_data, i.e. at
sdl_data[0]. The name of the interface occupies the next
sdl_nlen bytes and is not
NUL terminated. The link-layer network address begins
immediately after the interface name, and is
sdl_alen bytes long. The
macro
LLADDR(struct sockaddr_dl *) returns the start of the link-layer
network address. The interpretation of the link-layer address depends
on the value of
sdl_type. For example, if the type is
IFT_ETHER then
the address is expressed as a 6-byte MAC address.
struct sockaddr_ll The
sockaddr_ll is used as part of a socket type which is responsible
for packet capture:
AF_PACKET sockets. It is generally designed for
use with Ethernet networks. The members of the
struct sockaddr_ll are:
uint16_t sll_family; /* address family */
uint16_t sll_protocol; /* link layer protocol */
int32_t sll_ifindex; /* interface index */
uint16_t sll_hatype; /* ARP hardware type */
uint8_t sll_pkttype; /* packet type */
uint8_t sll_halen; /* hardware address length */
uint8_t sll_addr[8]; /* hardware type */
The member
sll_family must be
AF_PACKET. The member
sll_protocol refers to a link-layer protocol. For example, when capturing Ethernet
frames the value of
sll_protocol is the Ethertype. This member is
written in network byte order and applications should use
htons(3C) and
ntohs(3C) to read and write the member.
The member
sll_ifindex is the interface's index. It is used as an
identifier in various ioctls and included in the output of
ifconfig(8).
When calling
bind(3SOCKET) it should be filled in with the index that
corresponds to the interface for which packets should be captured on.
The member
sll_pkttype describes the type of the packet based on a list
of types in the header file <
netpacket/packet.h>. These types include:
PACKET_OUTGOING, a packet that was leaving the host and has been looped
back for packet capture;
PACKET_HOST, a packet that was destined for
this host;
PACKET_BROADCAST, a packet that was broadcast across the
link-layer;
PACKET_MULTICAST, a packet that was sent to a link-layer
multicast address; and
PACKET_OTHERHOST, a packet that was captured
only because the device in question was in promiscuous mode.
The member
sll_hatype contains the hardware type as defined by
arp(4P).
The list of types can be found in <
net/if_arp.h>. The member
sll_halen contains the length, in bytes, of the hardware address, while the
member
sll_addr contains the actual address in network byte order.
EXAMPLES
Example 1 Preparing an IPv4
sockaddr_in to connect to a remote host
The following example shows how one would open a socket and prepare it
to connect to the remote host whose address is the IP address 127.0.0.1
on port 80. This program should be compiled with the C compiler
cc and
linked against the libraries libsocket and libnsl. If this example was
named ip4.c, then the full link line would be
cc ip4.c -lsocket -lnsl.
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <strings.h>
int
main(void)
{
int sock;
struct sockaddr_in in;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
return (1);
}
bzero(&in, sizeof (struct sockaddr_in));
in.sin_family = AF_INET;
in.sin_port = htons(80);
if (inet_pton(AF_INET, "127.0.0.1", &in.sin_addr) != 1) {
perror("inet_pton");
return (1);
}
if (connect(sock, (struct sockaddr *)&in,
sizeof (struct sockaddr_in)) != 0) {
perror("connect");
return (1);
}
/* use socket */
return (0);
}
Example 2 Preparing an IPv6
sockaddr_in6 to bind to a local address
The following example shows how one would open a socket and prepare it
to bind to the local IPv6 address ::1 port on port 12345. This program
should be compiled with the C compiler
cc and linked against the
libraries libsocket and libnsl. If this example was named ip6.c, then
the full compiler line would be
cc ip6.c -lsocket -lnsl.
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <strings.h>
int
main(void)
{
int sock6;
struct sockaddr_in6 in6;
if ((sock6 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
perror("socket");
return (1);
}
bzero(&in6, sizeof (struct sockaddr_in6));
in6.sin6_family = AF_INET6;
in6.sin6_port = htons(12345);
if (inet_pton(AF_INET6, "::1", &in6.sin6_addr) != 1) {
perror("inet_pton");
return (1);
}
if (bind(sock6, (struct sockaddr *)&in6,
sizeof (struct sockaddr_in6)) != 0) {
perror("bind");
return (1);
}
/* use server socket */
return (0);
}
SEE ALSO
socket(3HEAD),
un.h(3HEAD),
accept(3SOCKET),
bind(3SOCKET),
connect(3SOCKET),
socket(3SOCKET),
arp(4P),
inet(4P),
inet6(4P),
ip(4P),
ip6(4P)illumos April 9, 2016 illumos