xref: /illumos-gate/usr/src/common/smbsrv/smb_inet.c (revision 49b5df1e)
17f667e74Sjose borrego /*
27f667e74Sjose borrego  * CDDL HEADER START
37f667e74Sjose borrego  *
47f667e74Sjose borrego  * The contents of this file are subject to the terms of the
57f667e74Sjose borrego  * Common Development and Distribution License (the "License").
67f667e74Sjose borrego  * You may not use this file except in compliance with the License.
77f667e74Sjose borrego  *
87f667e74Sjose borrego  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97f667e74Sjose borrego  * or http://www.opensolaris.org/os/licensing.
107f667e74Sjose borrego  * See the License for the specific language governing permissions
117f667e74Sjose borrego  * and limitations under the License.
127f667e74Sjose borrego  *
137f667e74Sjose borrego  * When distributing Covered Code, include this CDDL HEADER in each
147f667e74Sjose borrego  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157f667e74Sjose borrego  * If applicable, add the following below this CDDL HEADER, with the
167f667e74Sjose borrego  * fields enclosed by brackets "[]" replaced with your own identifying
177f667e74Sjose borrego  * information: Portions Copyright [yyyy] [name of copyright owner]
187f667e74Sjose borrego  *
197f667e74Sjose borrego  * CDDL HEADER END
207f667e74Sjose borrego  */
217f667e74Sjose borrego /*
227f667e74Sjose borrego  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237f667e74Sjose borrego  * Use is subject to license terms.
24b819cea2SGordon Ross  *
25b819cea2SGordon Ross  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
267f667e74Sjose borrego  */
277f667e74Sjose borrego 
287f667e74Sjose borrego /*
297f667e74Sjose borrego  * This file was originally generated using rpcgen.
307f667e74Sjose borrego  */
317f667e74Sjose borrego 
327f667e74Sjose borrego #include <sys/types.h>
337f667e74Sjose borrego #include <sys/socket.h>
347f667e74Sjose borrego #include <netinet/in.h>
35b819cea2SGordon Ross 
36b819cea2SGordon Ross #if !defined(_KERNEL)
37b819cea2SGordon Ross #include <errno.h>
38b819cea2SGordon Ross #include <string.h>
39b819cea2SGordon Ross #include <strings.h>
40b819cea2SGordon Ross #include <arpa/inet.h>
41b819cea2SGordon Ross #else	/* !_KERNEL */
42b819cea2SGordon Ross #include <sys/errno.h>
43b819cea2SGordon Ross #include <sys/sunddi.h>
44b819cea2SGordon Ross /* Don't want the rest of what's in inet/ip.h */
45b819cea2SGordon Ross extern char	*inet_ntop(int, const void *, char *, int);
46b819cea2SGordon Ross extern int	inet_pton(int, char *, void *);
47b819cea2SGordon Ross #endif	/* !_KERNEL */
48b819cea2SGordon Ross 
497f667e74Sjose borrego #include <smbsrv/smb_inet.h>
507f667e74Sjose borrego 
517f667e74Sjose borrego const struct in6_addr ipv6addr_any = IN6ADDR_ANY_INIT;
527f667e74Sjose borrego 
537f667e74Sjose borrego boolean_t
54fc724630SAlan Wright smb_inet_equal(smb_inaddr_t *ip1, smb_inaddr_t *ip2)
55fc724630SAlan Wright {
56fc724630SAlan Wright 	if ((ip1->a_family == AF_INET) &&
57fc724630SAlan Wright 	    (ip2->a_family == AF_INET) &&
58fc724630SAlan Wright 	    (ip1->a_ipv4 == ip2->a_ipv4))
59fc724630SAlan Wright 		return (B_TRUE);
60fc724630SAlan Wright 
61fc724630SAlan Wright 	if ((ip1->a_family == AF_INET6) &&
62fc724630SAlan Wright 	    (ip2->a_family == AF_INET6) &&
63b819cea2SGordon Ross 	    (!memcmp(&ip1->a_ipv6, &ip2->a_ipv6, sizeof (in6_addr_t))))
64fc724630SAlan Wright 		return (B_TRUE);
65fc724630SAlan Wright 	else
66fc724630SAlan Wright 		return (B_FALSE);
67fc724630SAlan Wright }
68fc724630SAlan Wright 
69fc724630SAlan Wright boolean_t
70fc724630SAlan Wright smb_inet_same_subnet(smb_inaddr_t *ip1, smb_inaddr_t *ip2, uint32_t v4mask)
717f667e74Sjose borrego {
727f667e74Sjose borrego 	if ((ip1->a_family == AF_INET) &&
737f667e74Sjose borrego 	    (ip2->a_family == AF_INET) &&
747f667e74Sjose borrego 	    ((ip1->a_ipv4 & v4mask) == (ip2->a_ipv4 & v4mask)))
757f667e74Sjose borrego 		return (B_TRUE);
767f667e74Sjose borrego 
777f667e74Sjose borrego 	if ((ip1->a_family == AF_INET6) &&
787f667e74Sjose borrego 	    (ip2->a_family == AF_INET6) &&
79b819cea2SGordon Ross 	    (!memcmp(&ip1->a_ipv6, &ip2->a_ipv6, sizeof (in6_addr_t))))
807f667e74Sjose borrego 		return (B_TRUE);
817f667e74Sjose borrego 	else
827f667e74Sjose borrego 		return (B_FALSE);
837f667e74Sjose borrego }
847f667e74Sjose borrego 
857f667e74Sjose borrego boolean_t
867f667e74Sjose borrego smb_inet_iszero(smb_inaddr_t *ipaddr)
877f667e74Sjose borrego {
887f667e74Sjose borrego 	const void *ipsz = (const void *)&ipv6addr_any;
897f667e74Sjose borrego 
907f667e74Sjose borrego 	if ((ipaddr->a_family == AF_INET) &&
917f667e74Sjose borrego 	    (ipaddr->a_ipv4 == 0))
927f667e74Sjose borrego 		return (B_TRUE);
937f667e74Sjose borrego 
947f667e74Sjose borrego 	if ((ipaddr->a_family == AF_INET6) &&
95b819cea2SGordon Ross 	    !memcmp(&ipaddr->a_ipv6, ipsz, sizeof (in6_addr_t)))
967f667e74Sjose borrego 		return (B_TRUE);
977f667e74Sjose borrego 	else
987f667e74Sjose borrego 		return (B_FALSE);
997f667e74Sjose borrego }
1007f667e74Sjose borrego 
1017f667e74Sjose borrego const char *
1027f667e74Sjose borrego smb_inet_ntop(smb_inaddr_t *addr, char *buf, int size)
1037f667e74Sjose borrego {
104b819cea2SGordon Ross 	/* Lint avoidance. */
105b819cea2SGordon Ross #if !defined(_KERNEL)
106b819cea2SGordon Ross 	size_t sz = (size_t)size;
107*49b5df1eSGordon Ross #else	/* _KERNEL */
108b819cea2SGordon Ross 	int sz = size;
109*49b5df1eSGordon Ross 
110*49b5df1eSGordon Ross 	/*
111*49b5df1eSGordon Ross 	 * Until uts/common/inet/ip/inet_ntop.c is fixed so it
112*49b5df1eSGordon Ross 	 * no longer uses leading zeros printing IPv4 addresses,
113*49b5df1eSGordon Ross 	 * we need to handle IPv4 ourselves.  If we leave the
114*49b5df1eSGordon Ross 	 * leading zeros, Windows clients get errors trying to
115*49b5df1eSGordon Ross 	 * resolve those address strings to names.  After:
116*49b5df1eSGordon Ross 	 * https://www.illumos.org/issues/5980 is fixed,
117*49b5df1eSGordon Ross 	 * this work-around can be removed.
118*49b5df1eSGordon Ross 	 */
119*49b5df1eSGordon Ross 	if (addr->a_family == AF_INET) {
120*49b5df1eSGordon Ross 		uint8_t *p = (void *) &addr->a_ipv4;
121*49b5df1eSGordon Ross 		(void) snprintf(buf, size, "%d.%d.%d.%d",
122*49b5df1eSGordon Ross 		    p[0], p[1], p[2], p[3]);
123*49b5df1eSGordon Ross 		return (buf);
124*49b5df1eSGordon Ross 	}
125*49b5df1eSGordon Ross #endif	/* _KERNEL */
126*49b5df1eSGordon Ross 
127b819cea2SGordon Ross 	return ((char *)inet_ntop(addr->a_family, addr, buf, sz));
1287f667e74Sjose borrego }
129