18.2 Datalink Socket Address
Structure
We will encounter datalink socket address
structures as return values contained in some of the messages
returned on a routing socket. Figure 18.1 shows the definition of the structure,
which is defined by including <net/if_dl.h>.
Figure 18.1
Datalink socket address structure.
struct sockaddr_dl {
uint8_t sdl_len;
sa_family_t sdl_family; /* AF_LINK */
uint16_t sdl_index; /* system assigned index, if > 0 */
uint8_t sdl_type; /* IFT_ETHER, etc. from <net/if_types.h> */
uint8_t sdl_nlen; /* name length, starting in sdl_data[0] */
uint8_t sdl_alen; /* link-layer address length */
uint8_t sdl_slen; /* link-layer selector length */
char sdl_data[12]; /* minimum work area, can be larger;
contains i/f name and link-layer address */
};
Each interface has a unique positive index, and
we will see this returned by the if_nametoindex and
if_nameindex functions later in this chapter, along with
the IPv6 multicasting socket options in Chapter 21 and some advanced IPv4
and IPv6 socket options in Chapter 27.
The sdl_data member contains both the
name and link-layer address (e.g., the 48-bit MAC address for an
Ethernet interface). The name begins at sdl_data[0] and is
not null-terminated. The link-layer address begins
sdl_nlen bytes after the name. This header defines the
following macro to return the pointer to the link-layer
address:
#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))
These socket address structures are
variable-length (p. 89 of TCPv2). If the link-layer address and
name exceed 12 bytes, the structure will be larger than 20 bytes.
The size is normally rounded up to the next multiple of 4 bytes on
32-bit systems. We will also see in Figure 22.3 that when
one of these structures is returned by the IP_RECVIF
socket option, all three lengths are 0 and there is no
sdl_data member at all.
|