[ Team LiB ] |
18.2 Datalink Socket Address StructureWe 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. |
[ Team LiB ] |