xref: /illumos-gate/usr/src/lib/libinetutil/common/inetutil.c (revision 23294c7da48c2eb5222bccedbefb1e06cf5c4df3)
1  /*
2   * CDDL HEADER START
3   *
4   * The contents of this file are subject to the terms of the
5   * Common Development and Distribution License (the "License").
6   * You may not use this file except in compliance with the License.
7   *
8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9   * or http://www.opensolaris.org/os/licensing.
10   * See the License for the specific language governing permissions
11   * and limitations under the License.
12   *
13   * When distributing Covered Code, include this CDDL HEADER in each
14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15   * If applicable, add the following below this CDDL HEADER, with the
16   * fields enclosed by brackets "[]" replaced with your own identifying
17   * information: Portions Copyright [yyyy] [name of copyright owner]
18   *
19   * CDDL HEADER END
20   */
21  
22  /*
23   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24   * Use is subject to license terms.
25   */
26  
27  #include <unistd.h>
28  #include <netinet/in.h>
29  #include <libinetutil.h>
30  
31  extern int getnetmaskbyaddr(const struct in_addr, struct in_addr *);
32  
33  /*
34   * Internet utility functions.
35   */
36  
37  /*
38   * Given a host-order address, calculate client's default net mask.
39   * Consult netmasks database to see if net is further subnetted.
40   * We'll only snag the first netmask that matches our criteria.
41   * We return the resultant netmask in host order.
42   */
43  void
44  get_netmask4(const struct in_addr *n_addrp, struct in_addr *s_addrp)
45  {
46  	struct in_addr	hp, tp;
47  
48  	/*
49  	 * First check if VLSM is in use.
50  	 */
51  	hp.s_addr = htonl(n_addrp->s_addr);
52  	if (getnetmaskbyaddr(hp, &tp) == 0) {
53  		s_addrp->s_addr = ntohl(tp.s_addr);
54  		return;
55  	}
56  
57  	/*
58  	 * Fall back on standard classed networks.
59  	 */
60  	if (IN_CLASSA(n_addrp->s_addr))
61  		s_addrp->s_addr = IN_CLASSA_NET;
62  	else if (IN_CLASSB(n_addrp->s_addr))
63  		s_addrp->s_addr = IN_CLASSB_NET;
64  	else if (IN_CLASSC(n_addrp->s_addr))
65  		s_addrp->s_addr = IN_CLASSC_NET;
66  	else
67  		s_addrp->s_addr = IN_CLASSE_NET;
68  }
69  
70  /*
71   * Checks if the IP addresses `ssp1' and `ssp2' are equal.
72   */
73  boolean_t
74  sockaddrcmp(const struct sockaddr_storage *ssp1,
75      const struct sockaddr_storage *ssp2)
76  {
77  	struct in_addr addr1, addr2;
78  	const struct in6_addr *addr6p1, *addr6p2;
79  
80  	if (ssp1->ss_family != ssp2->ss_family)
81  		return (B_FALSE);
82  
83  	if (ssp1 == ssp2)
84  		return (B_TRUE);
85  
86  	switch (ssp1->ss_family) {
87  	case AF_INET:
88  		addr1 = ((const struct sockaddr_in *)ssp1)->sin_addr;
89  		addr2 = ((const struct sockaddr_in *)ssp2)->sin_addr;
90  		return (addr1.s_addr == addr2.s_addr);
91  	case AF_INET6:
92  		addr6p1 = &((const struct sockaddr_in6 *)ssp1)->sin6_addr;
93  		addr6p2 = &((const struct sockaddr_in6 *)ssp2)->sin6_addr;
94  		return (IN6_ARE_ADDR_EQUAL(addr6p1, addr6p2));
95  	}
96  	return (B_FALSE);
97  }
98