diff options
author | Darren Reed <Darren.Reed@Oracle.COM> | 2010-07-09 21:00:59 -0700 |
---|---|---|
committer | Darren Reed <Darren.Reed@Oracle.COM> | 2010-07-09 21:00:59 -0700 |
commit | 64639aaf7beb84086b88f186ea1fa9ccf0be8c57 (patch) | |
tree | 1c189cfff212c6e13f229c55a5b6c1842bb7a168 /usr/src/lib/libinetutil/common | |
parent | f9e0b1dc6f25356fd35837dc9e1124b2d91ed6f3 (diff) | |
download | illumos-joyent-64639aaf7beb84086b88f186ea1fa9ccf0be8c57.tar.gz |
6950944 ifa_addr and friends should be "sockaddr", not "sockaddr_storage"
Diffstat (limited to 'usr/src/lib/libinetutil/common')
-rw-r--r-- | usr/src/lib/libinetutil/common/inetutil.c | 55 | ||||
-rw-r--r-- | usr/src/lib/libinetutil/common/libinetutil.h | 10 |
2 files changed, 37 insertions, 28 deletions
diff --git a/usr/src/lib/libinetutil/common/inetutil.c b/usr/src/lib/libinetutil/common/inetutil.c index be92c0e77d..f336f95720 100644 --- a/usr/src/lib/libinetutil/common/inetutil.c +++ b/usr/src/lib/libinetutil/common/inetutil.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <unistd.h> @@ -29,6 +28,7 @@ #include <libinetutil.h> #include <inet/ip.h> #include <strings.h> +#include <stddef.h> #include <errno.h> #include <libsocket_priv.h> @@ -100,26 +100,33 @@ sockaddrcmp(const struct sockaddr_storage *ssp1, /* * Stores the netmask in `mask' for the given prefixlen `plen' and also sets - * `ss_family' in `mask'. + * `sa_family' in `mask'. Because this function does not require aligned + * access to the data inside of the sockaddr_in/6 structures, the code can + * use offsetof() to find the right place in the incoming structure. Why is + * using that beneficial? Less issues with lint. When using a direct cast + * of the struct sockaddr_storage structure to sockaddr_in6, a lint warning + * is generated because the former is composed of 16bit & 8bit elements whilst + * sockaddr_in6 has a 32bit alignment requirement. */ int -plen2mask(uint_t prefixlen, sa_family_t af, struct sockaddr_storage *mask) +plen2mask(uint_t prefixlen, sa_family_t af, struct sockaddr *mask) { uint8_t *addr; - bzero(mask, sizeof (*mask)); - mask->ss_family = af; if (af == AF_INET) { if (prefixlen > IP_ABITS) return (EINVAL); - addr = (uint8_t *)&((struct sockaddr_in *)mask)-> - sin_addr.s_addr; + bzero(mask, sizeof (struct sockaddr_in)); + addr = (uint8_t *)mask; + addr += offsetof(struct sockaddr_in, sin_addr); } else { if (prefixlen > IPV6_ABITS) return (EINVAL); - addr = (uint8_t *)&((struct sockaddr_in6 *)mask)-> - sin6_addr.s6_addr; + bzero(mask, sizeof (struct sockaddr_in6)); + addr = (uint8_t *)mask; + addr += offsetof(struct sockaddr_in6, sin6_addr); } + mask->sa_family = af; while (prefixlen > 0) { if (prefixlen >= 8) { @@ -136,23 +143,25 @@ plen2mask(uint_t prefixlen, sa_family_t af, struct sockaddr_storage *mask) /* * Convert a mask to a prefix length. * Returns prefix length on success, -1 otherwise. + * The comments (above) for plen2mask about the use of `mask' also apply + * to this function and the choice to use offsetof here too. */ int -mask2plen(const struct sockaddr_storage *mask) +mask2plen(const struct sockaddr *mask) { int rc = 0; uint8_t last; uint8_t *addr; int limit; - if (mask->ss_family == AF_INET) { + if (mask->sa_family == AF_INET) { limit = IP_ABITS; - addr = (uint8_t *)&((struct sockaddr_in *)mask)-> - sin_addr.s_addr; + addr = (uint8_t *)mask; + addr += offsetof(struct sockaddr_in, sin_addr); } else { limit = IPV6_ABITS; - addr = (uint8_t *)&((struct sockaddr_in6 *)mask)-> - sin6_addr.s6_addr; + addr = (uint8_t *)mask; + addr += offsetof(struct sockaddr_in6, sin6_addr); } while (*addr == 0xff) { @@ -176,18 +185,20 @@ mask2plen(const struct sockaddr_storage *mask) * :: for IPv6. Otherwise, returns B_FALSE. */ boolean_t -sockaddrunspec(const struct sockaddr_storage *ss) +sockaddrunspec(const struct sockaddr *ss) { - struct sockaddr_storage zeroaddr = {0}; + struct sockaddr_storage data; - switch (ss->ss_family) { + switch (ss->sa_family) { case AF_INET: - return (((struct sockaddr_in *)ss)->sin_addr.s_addr == + (void) memcpy(&data, ss, sizeof (struct sockaddr_in)); + return (((struct sockaddr_in *)&data)->sin_addr.s_addr == INADDR_ANY); case AF_INET6: + (void) memcpy(&data, ss, sizeof (struct sockaddr_in6)); return (IN6_IS_ADDR_UNSPECIFIED( - &((struct sockaddr_in6 *)ss)->sin6_addr)); + &((struct sockaddr_in6 *)&data)->sin6_addr)); } - return (bcmp(&zeroaddr, ss, sizeof (zeroaddr)) == 0); + return (B_FALSE); } diff --git a/usr/src/lib/libinetutil/common/libinetutil.h b/usr/src/lib/libinetutil/common/libinetutil.h index d294e6b50c..2e854f1186 100644 --- a/usr/src/lib/libinetutil/common/libinetutil.h +++ b/usr/src/lib/libinetutil/common/libinetutil.h @@ -20,8 +20,7 @@ */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _LIBINETUTIL_H @@ -54,10 +53,9 @@ extern boolean_t ifparse_ifspec(const char *, ifspec_t *); extern void get_netmask4(const struct in_addr *, struct in_addr *); extern boolean_t sockaddrcmp(const struct sockaddr_storage *, const struct sockaddr_storage *); -extern int plen2mask(uint_t, sa_family_t, - struct sockaddr_storage *); -extern int mask2plen(const struct sockaddr_storage *); -extern boolean_t sockaddrunspec(const struct sockaddr_storage *); +extern int plen2mask(uint_t, sa_family_t, struct sockaddr *); +extern int mask2plen(const struct sockaddr *); +extern boolean_t sockaddrunspec(const struct sockaddr *); /* * Extended version of the classic BSD ifaddrlist() interface: |