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