3 Subroutines to manipulate internet addresses in a safely portable
7 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 1995-2003 by Internet Software Consortium
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
14 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 * Internet Systems Consortium, Inc.
24 * Redwood City, CA 94063
28 * This software has been written for Internet Systems Consortium
29 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
30 * To learn more about Internet Systems Consortium, see
31 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
32 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
33 * ``http://www.nominum.com''.
37 static char copyright[] =
38 "$Id: inet.c,v 1.8.2.5 2004/06/10 17:59:18 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
43 /* Return just the network number of an internet address... */
45 struct iaddr subnet_number (addr, mask)
54 /* Both addresses must have the same length... */
55 if (addr.len != mask.len)
59 for (i = 0; i < rv.len; i++)
60 rv.iabuf [i] = addr.iabuf [i] & mask.iabuf [i];
64 /* Combine a network number and a integer to produce an internet address.
65 This won't work for subnets with more than 32 bits of host address, but
66 maybe this isn't a problem. */
68 struct iaddr ip_addr (subnet, mask, host_address)
71 u_int32_t host_address;
76 unsigned char habuf [sizeof swaddr];
78 swaddr = htonl (host_address);
79 memcpy (habuf, &swaddr, sizeof swaddr);
81 /* Combine the subnet address and the host address. If
82 the host address is bigger than can fit in the subnet,
83 return a zero-length iaddr structure. */
85 j = rv.len - sizeof habuf;
86 for (i = sizeof habuf - 1; i >= 0; i--) {
87 if (mask.iabuf [i + j]) {
88 if (habuf [i] > (mask.iabuf [i + j] ^ 0xFF)) {
92 for (k = i - 1; k >= 0; k--) {
98 rv.iabuf [i + j] |= habuf [i];
101 rv.iabuf [i + j] = habuf [i];
107 /* Given a subnet number and netmask, return the address on that subnet
108 for which the host portion of the address is all ones (the standard
109 broadcast address). */
111 struct iaddr broadcast_addr (subnet, mask)
118 if (subnet.len != mask.len) {
123 for (i = 0; i < subnet.len; i++) {
124 rv.iabuf [i] = subnet.iabuf [i] | (~mask.iabuf [i] & 255);
131 u_int32_t host_addr (addr, mask)
141 /* Mask out the network bits... */
143 for (i = 0; i < rv.len; i++)
144 rv.iabuf [i] = addr.iabuf [i] & ~mask.iabuf [i];
146 /* Copy out up to 32 bits... */
147 memcpy (&swaddr, &rv.iabuf [rv.len - sizeof swaddr], sizeof swaddr);
149 /* Swap it and return it. */
150 return ntohl (swaddr);
153 int addr_eq (addr1, addr2)
154 struct iaddr addr1, addr2;
156 if (addr1.len != addr2.len)
158 return memcmp (addr1.iabuf, addr2.iabuf, addr1.len) == 0;
164 static char pbuf [4 * 16];
169 strcpy (s, "<null address>");
171 for (i = 0; i < addr.len; i++) {
172 sprintf (s, "%s%d", i ? "." : "", addr.iabuf [i]);
181 static char pbuf [4 * 16];
186 strcpy (s, "<null address>");
188 for (i = 0; i < addr.len; i++) {
189 sprintf (s, "%s%d", i ? "." : "", addr.iabuf [i]);
195 char *piaddrmask (struct iaddr addr, struct iaddr mask,
196 const char *file, int line)
202 for (i = 0; i < 32; i++) {
203 if (!mask.iabuf [3 - i / 8])
205 else if (mask.iabuf [3 - i / 8] & (1 << (i % 8)))
209 len = mw > 9 ? 2 : 1;
210 len += 4; /* three dots and a slash. */
211 for (i = 0; i < (mw / 8) + 1; i++) {
212 if (addr.iabuf [i] > 99)
214 else if (addr.iabuf [i] > 9)
219 s = dmalloc (len + 1, file, line);
223 sprintf (t, "%d", addr.iabuf [0]);
225 for (i = 1; i < (mw / 8) + 1; i++) {
226 sprintf (t, ".%d", addr.iabuf [i]);
230 sprintf (t, "%d", mw);