1 /* LWIP service - addr.c - socket address verification and conversion */
6 * Return TRUE if the given socket address is of type AF_UNSPEC, or FALSE
10 addr_is_unspec(const struct sockaddr
* addr
, socklen_t addr_len
)
13 return (addr_len
>= offsetof(struct sockaddr
, sa_data
) &&
14 addr
->sa_family
== AF_UNSPEC
);
18 * Check whether the given multicast address is generally valid. This check
19 * should not be moved into addr_get_inet(), as we do not want to forbid
20 * creating routes for such addresses, for example. We do however apply the
21 * restrictions here to all provided source and destination addresses. Return
22 * TRUE if the address is an acceptable multicast address, or FALSE otherwise.
25 addr_is_valid_multicast(const ip_addr_t
* ipaddr
)
29 assert(ip_addr_ismulticast(ipaddr
));
31 /* We apply restrictions to IPv6 multicast addresses only. */
32 if (IP_IS_V6(ipaddr
)) {
33 scope
= ip6_addr_multicast_scope(ip_2_ip6(ipaddr
));
35 if (scope
== IP6_MULTICAST_SCOPE_RESERVED0
||
36 scope
== IP6_MULTICAST_SCOPE_RESERVEDF
)
40 * We do not impose restrictions on the three defined embedded
41 * flags, even though we put no effort into supporting them,
42 * especially in terms of automatically creating routes for
43 * all cases. We do force the fourth flag to be zero.
44 * Unfortunately there is no lwIP macro to check for this flag.
46 if (ip_2_ip6(ipaddr
)->addr
[0] & PP_HTONL(0x00800000UL
))
49 /* Prevent KAME-embedded zone IDs from entering the system. */
50 if (ip6_addr_has_scope(ip_2_ip6(ipaddr
), IP6_UNKNOWN
) &&
51 (ip_2_ip6(ipaddr
)->addr
[0] & PP_HTONL(0x0000ffffUL
)))
59 * Load a sockaddr structure, as copied from userland, as a lwIP-style IP
60 * address and (optionally) a port number. The expected type of IP address is
61 * given as 'type', which must be one of IPADDR_TYPE_{V4,ANY,V6}. If it is
62 * IPADDR_TYPE_V4, 'addr' is expected to point to a sockaddr_in structure. If
63 * it is IPADDR_TYPE_{ANY,V6}, 'addr' is expected to point to a sockaddr_in6
64 * structure. For the _ANY case, the result will be an _ANY address only if it
65 * is the unspecified (all-zeroes) address and a _V6 address in all other
66 * cases. For the _V6 case, the result will always be a _V6 address. The
67 * length of the structure pointed to by 'addr' is given as 'addr_len'. If the
68 * boolean 'kame' flag is set, addresses will be interpreted to be KAME style,
69 * meaning that for scoped IPv6 addresses, the zone is embedded in the address
70 * rather than given in sin6_scope_id. On success, store the resulting IP
71 * address in 'ipaddr'. If 'port' is not NULL, store the port number in it;
72 * otherwise, ignore the port number. On any parsing failure, return an
73 * appropriate negative error code.
76 addr_get_inet(const struct sockaddr
* addr
, socklen_t addr_len
, uint8_t type
,
77 ip_addr_t
* ipaddr
, int kame
, uint16_t * port
)
79 struct sockaddr_in sin
;
80 struct sockaddr_in6 sin6
;
86 if (addr_len
!= sizeof(sin
))
90 * Getting around strict aliasing problems. Oh, the irony of
91 * doing an extra memcpy so that the compiler can do a better
94 memcpy(&sin
, addr
, sizeof(sin
));
96 if (sin
.sin_family
!= AF_INET
)
99 ip_addr_set_ip4_u32(ipaddr
, sin
.sin_addr
.s_addr
);
102 *port
= ntohs(sin
.sin_port
);
106 case IPADDR_TYPE_ANY
:
108 if (addr_len
!= sizeof(sin6
))
111 /* Again, strict aliasing.. */
112 memcpy(&sin6
, addr
, sizeof(sin6
));
114 if (sin6
.sin6_family
!= AF_INET6
)
117 memset(ipaddr
, 0, sizeof(*ipaddr
));
120 * This is a bit ugly, but NetBSD does not expose s6_addr32 and
121 * s6_addr is a series of bytes, which is a mismatch for lwIP.
122 * The alternative would be another memcpy..
124 ip6addr
= ip_2_ip6(ipaddr
);
125 assert(sizeof(ip6addr
->addr
) == sizeof(sin6
.sin6_addr
));
126 memcpy(ip6addr
->addr
, &sin6
.sin6_addr
, sizeof(ip6addr
->addr
));
129 * If the address may have a scope, extract the zone ID.
130 * Where the zone ID is depends on the 'kame' parameter: KAME-
131 * style addresses have it embedded within the address, whereas
132 * non-KAME addresses use the (misnamed) sin6_scope_id field.
134 if (ip6_addr_has_scope(ip6addr
, IP6_UNKNOWN
)) {
137 ntohl(ip6addr
->addr
[0]) & 0x0000ffffUL
;
139 ip6addr
->addr
[0] &= PP_HTONL(0xffff0000UL
);
142 * Reject KAME-style addresses for normal
143 * socket calls, to save ourselves the trouble
144 * of mixed address styles elsewhere.
146 if (ip6addr
->addr
[0] & PP_HTONL(0x0000ffffUL
))
149 ifindex
= sin6
.sin6_scope_id
;
153 * Reject invalid zone IDs. This also enforces that
154 * no zone IDs wider than eight bits enter the system.
155 * As a side effect, it is not possible to add routes
156 * for invalid zones, but that should be no problem.
159 ifdev_get_by_index(ifindex
) == NULL
)
162 ip6_addr_set_zone(ip6addr
, ifindex
);
164 ip6_addr_clear_zone(ip6addr
);
167 * Set the type to ANY if it was ANY and the address itself is
168 * ANY as well. Otherwise, we are binding to a specific IPv6
169 * address, so IPV6_V6ONLY stops being relevant and we should
170 * leave the address set to V6. Destination addresses for ANY
171 * are set to V6 elsewhere.
173 if (type
== IPADDR_TYPE_ANY
&& ip6_addr_isany(ip6addr
))
174 IP_SET_TYPE(ipaddr
, type
);
176 IP_SET_TYPE(ipaddr
, IPADDR_TYPE_V6
);
179 *port
= ntohs(sin6
.sin6_port
);
189 * Store an lwIP-style IP address and port number as a sockaddr structure
190 * (sockaddr_in or sockaddr_in6, depending on the given IP address) to be
191 * copied to userland. The result is stored in the buffer pointed to by
192 * 'addr'. Before the call, 'addr_len' must be set to the size of this buffer.
193 * This is an internal check to prevent buffer overflows, and must not be used
194 * to validate input, since a mismatch will trigger a panic. After the call,
195 * 'addr_len' will be set to the size of the resulting structure. The lwIP-
196 * style address is given as 'ipaddr'. If the boolean 'kame' flag is set, the
197 * address will be stored KAME-style, meaning that for scoped IPv6 addresses,
198 * the address zone will be stored embedded in the address rather than in
199 * sin6_scope_id. If relevant, 'port' contains the port number in host-byte
200 * order; otherwise it should be set to zone.
203 addr_put_inet(struct sockaddr
* addr
, socklen_t
* addr_len
,
204 const ip_addr_t
* ipaddr
, int kame
, uint16_t port
)
206 struct sockaddr_in sin
;
207 struct sockaddr_in6 sin6
;
208 const ip6_addr_t
*ip6addr
;
211 switch (IP_GET_TYPE(ipaddr
)) {
213 if (*addr_len
< sizeof(sin
))
214 panic("provided address buffer too small");
216 memset(&sin
, 0, sizeof(sin
));
218 sin
.sin_len
= sizeof(sin
);
219 sin
.sin_family
= AF_INET
;
220 sin
.sin_port
= htons(port
);
221 sin
.sin_addr
.s_addr
= ip_addr_get_ip4_u32(ipaddr
);
223 memcpy(addr
, &sin
, sizeof(sin
));
224 *addr_len
= sizeof(sin
);
228 case IPADDR_TYPE_ANY
:
230 if (*addr_len
< sizeof(sin6
))
231 panic("provided address buffer too small");
233 ip6addr
= ip_2_ip6(ipaddr
);
235 memset(&sin6
, 0, sizeof(sin6
));
237 sin6
.sin6_len
= sizeof(sin6
);
238 sin6
.sin6_family
= AF_INET6
;
239 sin6
.sin6_port
= htons(port
);
240 memcpy(&sin6
.sin6_addr
, ip6addr
->addr
, sizeof(sin6
.sin6_addr
));
243 * If the IPv6 address has a zone set, it must be scoped, and
244 * we put the zone in the result. It may occur that a scoped
245 * IPv6 address does not have a zone here though, for example
246 * if packet routing fails for sendto() with a zoneless address
247 * on an unbound socket, resulting in an RTM_MISS message. In
248 * such cases, simply leave the zone index blank in the result.
250 if (ip6_addr_has_zone(ip6addr
)) {
251 assert(ip6_addr_has_scope(ip6addr
, IP6_UNKNOWN
));
253 zone
= ip6_addr_zone(ip6addr
);
254 assert(zone
<= UINT8_MAX
);
257 sin6
.sin6_addr
.s6_addr
[3] = zone
;
259 sin6
.sin6_scope_id
= zone
;
262 memcpy(addr
, &sin6
, sizeof(sin6
));
263 *addr_len
= sizeof(sin6
);
268 panic("unknown IP address type: %u", IP_GET_TYPE(ipaddr
));
273 * Load a link-layer sockaddr structure (sockaddr_dl), as copied from userland,
274 * and return the contained name and/or hardware address. The address is
275 * provided as 'addr', with length 'addr_len'. On success, return OK. If
276 * 'name' is not NULL, it must be of size 'name_max', and will be used to store
277 * the (null-terminated) interface name in the given structure if present, or
278 * the empty string if not. If 'hwaddr' is not NULL, it will be used to store
279 * the hardware address in the given structure, which must in that case be
280 * present and exactly 'hwaddr_len' bytes long. On any parsing failure, return
281 * an appropriate negative error code.
284 addr_get_link(const struct sockaddr
* addr
, socklen_t addr_len
, char * name
,
285 size_t name_max
, uint8_t * hwaddr
, size_t hwaddr_len
)
287 struct sockaddr_dlx sdlx
;
290 if (addr_len
< offsetof(struct sockaddr_dlx
, sdlx_data
))
294 * We cannot prevent callers from passing in massively oversized
295 * sockaddr_dl structure. However, we insist that all the actual data
296 * be contained within the size of our sockaddr_dlx version.
298 if (addr_len
> sizeof(sdlx
))
299 addr_len
= sizeof(sdlx
);
301 memcpy(&sdlx
, addr
, addr_len
);
303 if (sdlx
.sdlx_family
!= AF_LINK
)
306 /* Address selectors are not currently supported. */
307 if (sdlx
.sdlx_slen
!= 0)
310 nlen
= (size_t)sdlx
.sdlx_nlen
;
311 alen
= (size_t)sdlx
.sdlx_alen
;
313 /* The nlen and alen fields are 8-bit, so no risks of overflow here. */
314 if (addr_len
< offsetof(struct sockaddr_dlx
, sdlx_data
) + nlen
+ alen
)
318 * Copy out the name, truncating it if needed. The name in the
319 * sockaddr is not null terminated, so we have to do that. If the
320 * sockaddr has no name, copy out an empty name.
323 assert(name_max
> 0);
325 if (name_max
> nlen
+ 1)
328 memcpy(name
, sdlx
.sdlx_data
, name_max
- 1);
329 name
[name_max
- 1] = '\0';
333 * Copy over the hardware address. For simplicity, we require that the
334 * caller specify the exact hardware address length.
336 if (hwaddr
!= NULL
) {
337 if (alen
!= hwaddr_len
)
340 memcpy(hwaddr
, sdlx
.sdlx_data
+ nlen
, hwaddr_len
);
347 * Store a link-layer sockaddr structure (sockaddr_dl), to be copied to
348 * userland. The result is stored in the buffer pointed to by 'addr'. Before
349 * the call, 'addr_len' must be set to the size of this buffer. This is an
350 * internal check to prevent buffer overflows, and must not be used to validate
351 * input, since a mismatch will trigger a panic. After the call, 'addr_len'
352 * will be set to the size of the resulting structure. The given interface
353 * index 'ifindex' and (IFT_) interface type 'type' will always be stored in
354 * the resulting structure. If 'name' is not NULL, it must be a null-
355 * terminated interface name string which will be included in the structure.
356 * If 'hwaddr' is not NULL, it must be a hardware address of length
357 * 'hwaddr_len', which will also be included in the structure.
360 addr_put_link(struct sockaddr
* addr
, socklen_t
* addr_len
, uint32_t ifindex
,
361 uint32_t type
, const char * name
, const uint8_t * hwaddr
,
364 struct sockaddr_dlx sdlx
;
368 name_len
= (name
!= NULL
) ? strlen(name
) : 0;
373 assert(name_len
< IFNAMSIZ
);
374 assert(hwaddr_len
<= NETIF_MAX_HWADDR_LEN
);
376 len
= offsetof(struct sockaddr_dlx
, sdlx_data
) + name_len
+ hwaddr_len
;
379 panic("provided address buffer too small");
381 memset(&sdlx
, 0, sizeof(sdlx
));
383 sdlx
.sdlx_family
= AF_LINK
;
384 sdlx
.sdlx_index
= ifindex
;
385 sdlx
.sdlx_type
= type
;
386 sdlx
.sdlx_nlen
= name_len
;
387 sdlx
.sdlx_alen
= hwaddr_len
;
389 memcpy(sdlx
.sdlx_data
, name
, name_len
);
391 memcpy(sdlx
.sdlx_data
+ name_len
, hwaddr
, hwaddr_len
);
393 memcpy(addr
, &sdlx
, len
);
398 * Convert an IPv4 or IPv6 netmask, given as sockaddr structure 'addr', to a
399 * prefix length. The length of the sockaddr structure is given as 'addr_len'.
400 * For consistency with addr_get_inet(), the expected address type is given as
401 * 'type', and must be either IPADDR_TYPE_V4 or IPADDR_TYPE_V6. On success,
402 * return OK with the number of set prefix bits returned in 'prefix', and
403 * optionally with a lwIP representation of the netmask stored in 'ipaddr' (if
404 * not NULL). On failure, return an appropriate negative error code. Note
405 * that this function does not support compressed IPv4 network masks; such
406 * addresses must be expanded before a call to this function.
409 addr_get_netmask(const struct sockaddr
* addr
, socklen_t addr_len
,
410 uint8_t type
, unsigned int * prefix
, ip_addr_t
* ipaddr
)
412 struct sockaddr_in sin
;
413 struct sockaddr_in6 sin6
;
414 unsigned int byte
, bit
;
419 if (addr_len
!= sizeof(sin
))
422 memcpy(&sin
, addr
, sizeof(sin
));
424 if (sin
.sin_family
!= AF_INET
)
427 val
= ntohl(sin
.sin_addr
.s_addr
);
429 /* Find the first zero bit. */
430 for (bit
= 0; bit
< IP4_BITS
; bit
++)
431 if (!(val
& (1 << (IP4_BITS
- bit
- 1))))
436 /* All bits after the first zero bit must also be zero. */
437 if (bit
< IP4_BITS
&&
438 (val
& ((1 << (IP4_BITS
- bit
- 1)) - 1)))
442 ip_addr_set_ip4_u32(ipaddr
, sin
.sin_addr
.s_addr
);
447 if (addr_len
!= sizeof(sin6
))
450 memcpy(&sin6
, addr
, sizeof(sin6
));
452 if (sin6
.sin6_family
!= AF_INET6
)
455 /* Find the first zero bit. */
456 for (byte
= 0; byte
< __arraycount(sin6
.sin6_addr
.s6_addr
);
458 if (sin6
.sin6_addr
.s6_addr
[byte
] != 0xff)
461 /* If all bits are set, there is nothing more to do. */
462 if (byte
== __arraycount(sin6
.sin6_addr
.s6_addr
)) {
463 *prefix
= __arraycount(sin6
.sin6_addr
.s6_addr
) * NBBY
;
468 for (bit
= 0; bit
< NBBY
; bit
++)
469 if (!(sin6
.sin6_addr
.s6_addr
[byte
] &
470 (1 << (NBBY
- bit
- 1))))
473 *prefix
= byte
* NBBY
+ bit
;
475 /* All bits after the first zero bit must also be zero. */
476 if (bit
< NBBY
&& (sin6
.sin6_addr
.s6_addr
[byte
] &
477 ((1 << (NBBY
- bit
- 1)) - 1)))
480 for (byte
++; byte
< __arraycount(sin6
.sin6_addr
.s6_addr
);
482 if (sin6
.sin6_addr
.s6_addr
[byte
] != 0)
485 if (ipaddr
!= NULL
) {
486 ip_addr_set_zero_ip6(ipaddr
);
488 memcpy(ip_2_ip6(ipaddr
)->addr
, &sin6
.sin6_addr
,
489 sizeof(ip_2_ip6(ipaddr
)->addr
));
495 panic("unknown IP address type: %u", type
);
500 * Generate a raw network mask based on the given prefix length.
503 addr_make_netmask(uint8_t * addr
, socklen_t addr_len
, unsigned int prefix
)
505 unsigned int byte
, bit
;
507 byte
= prefix
/ NBBY
;
510 assert(byte
+ !!bit
<= addr_len
);
513 memset(addr
, 0xff, byte
);
515 addr
[byte
++] = (uint8_t)(0xff << (NBBY
- bit
));
517 memset(&addr
[byte
], 0, addr_len
- byte
);
521 * Store a network mask as a sockaddr structure, in 'addr'. Before the call,
522 * 'addr_len' must be set to the memory size of 'addr'. The address type is
523 * given as 'type', and must be either IPADDR_TYPE_V4 or IPADDR_TYPE_V6. The
524 * prefix length from which to generate the network mask is given as 'prefix'.
525 * Upon return, 'addr_len' is set to the size of the resulting sockaddr
529 addr_put_netmask(struct sockaddr
* addr
, socklen_t
* addr_len
, uint8_t type
,
532 struct sockaddr_in sin
;
533 struct sockaddr_in6 sin6
;
537 if (*addr_len
< sizeof(sin
))
538 panic("provided address buffer too small");
540 assert(prefix
<= IP4_BITS
);
542 memset(&sin
, 0, sizeof(sin
));
543 sin
.sin_len
= sizeof(sin
);
544 sin
.sin_family
= AF_INET
;
546 addr_make_netmask((uint8_t *)&sin
.sin_addr
.s_addr
,
547 sizeof(sin
.sin_addr
.s_addr
), prefix
);
549 memcpy(addr
, &sin
, sizeof(sin
));
550 *addr_len
= sizeof(sin
);
555 if (*addr_len
< sizeof(sin6
))
556 panic("provided address buffer too small");
558 assert(prefix
<= IP6_BITS
);
560 memset(&sin6
, 0, sizeof(sin6
));
561 sin6
.sin6_len
= sizeof(sin6
);
562 sin6
.sin6_family
= AF_INET6
;
564 addr_make_netmask(sin6
.sin6_addr
.s6_addr
,
565 sizeof(sin6
.sin6_addr
.s6_addr
), prefix
);
567 memcpy(addr
, &sin6
, sizeof(sin6
));
568 *addr_len
= sizeof(sin6
);
573 panic("unknown IP address type: %u", type
);
578 * Normalize the given address in 'src' to the given number of prefix bits,
579 * setting all other bits to zero. Return the result in 'dst'.
582 addr_normalize(ip_addr_t
* dst
, const ip_addr_t
* src
, unsigned int prefix
)
585 unsigned int addr_len
;
586 #endif /* !defined(NDEBUG) */
587 unsigned int byte
, bit
;
588 const uint8_t *srcaddr
;
589 uint8_t type
, *dstaddr
;
591 type
= IP_GET_TYPE(src
);
593 memset(dst
, 0, sizeof(*dst
));
594 IP_SET_TYPE(dst
, type
);
598 srcaddr
= (const uint8_t *)&ip_2_ip4(src
)->addr
;
599 dstaddr
= (uint8_t *)&ip_2_ip4(dst
)->addr
;
601 addr_len
= sizeof(ip_2_ip4(src
)->addr
);
602 #endif /* !defined(NDEBUG) */
607 ip6_addr_set_zone(ip_2_ip6(dst
), ip6_addr_zone(ip_2_ip6(src
)));
609 srcaddr
= (const uint8_t *)&ip_2_ip6(src
)->addr
;
610 dstaddr
= (uint8_t *)&ip_2_ip6(dst
)->addr
;
612 addr_len
= sizeof(ip_2_ip6(src
)->addr
);
613 #endif /* !defined(NDEBUG) */
618 panic("unknown IP address type: %u", type
);
621 byte
= prefix
/ NBBY
;
624 assert(byte
+ !!bit
<= addr_len
);
627 memcpy(dstaddr
, srcaddr
, byte
);
630 srcaddr
[byte
] & (uint8_t)(0xff << (NBBY
- bit
));
636 * Return the number of common bits between the given two addresses, up to the
637 * given maximum. Thus, return a value between 0 and 'max' inclusive.
640 addr_get_common_bits(const ip_addr_t
* ipaddr1
, const ip_addr_t
* ipaddr2
,
643 unsigned int addr_len
, prefix
, bit
;
644 const uint8_t *addr1
, *addr2
;
647 switch (IP_GET_TYPE(ipaddr1
)) {
649 assert(IP_IS_V4(ipaddr2
));
651 addr1
= (const uint8_t *)&ip_2_ip4(ipaddr1
)->addr
;
652 addr2
= (const uint8_t *)&ip_2_ip4(ipaddr2
)->addr
;
653 addr_len
= sizeof(ip_2_ip4(ipaddr1
)->addr
);
658 assert(IP_IS_V6(ipaddr2
));
660 addr1
= (const uint8_t *)&ip_2_ip6(ipaddr1
)->addr
;
661 addr2
= (const uint8_t *)&ip_2_ip6(ipaddr2
)->addr
;
662 addr_len
= sizeof(ip_2_ip6(ipaddr1
)->addr
);
667 panic("unknown IP address type: %u", IP_GET_TYPE(ipaddr1
));
670 if (addr_len
> max
* NBBY
)
671 addr_len
= max
* NBBY
;
675 for (prefix
= 0; addr_len
> 0; addr1
++, addr2
++, prefix
+= NBBY
) {
676 if ((byte
= (*addr1
^ *addr2
)) != 0) {
677 /* TODO: see if we want a lookup table for this. */
678 for (bit
= 0; bit
< NBBY
; bit
++, prefix
++)
679 if (byte
& (1 << (NBBY
- bit
- 1)))
692 * Convert the given IPv4 address to an IPv4-mapped IPv6 address.
695 addr_make_v4mapped_v6(ip_addr_t
* dst
, const ip4_addr_t
* src
)
698 IP_ADDR6(dst
, 0, 0, PP_HTONL(0x0000ffffUL
), ip4_addr_get_u32(src
));