3 Subroutines to manipulate internet addresses in a safely portable
7 * Copyright (c) 1995-2002 Internet Software Consortium.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of The Internet Software Consortium nor the names
20 * of its contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
24 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
31 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * This software has been written for the Internet Software Consortium
38 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
39 * To learn more about the Internet Software Consortium, see
40 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
41 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
42 * ``http://www.nominum.com''.
46 static char copyright[] =
47 "$Id: inet.c,v 1.8.2.4 2002/11/17 02:26:58 dhankins Exp $ Copyright (c) 1995-2002 The Internet Software Consortium. All rights reserved.\n";
52 /* Return just the network number of an internet address... */
54 struct iaddr subnet_number (addr, mask)
63 /* Both addresses must have the same length... */
64 if (addr.len != mask.len)
68 for (i = 0; i < rv.len; i++)
69 rv.iabuf [i] = addr.iabuf [i] & mask.iabuf [i];
73 /* Combine a network number and a integer to produce an internet address.
74 This won't work for subnets with more than 32 bits of host address, but
75 maybe this isn't a problem. */
77 struct iaddr ip_addr (subnet, mask, host_address)
80 u_int32_t host_address;
85 unsigned char habuf [sizeof swaddr];
87 swaddr = htonl (host_address);
88 memcpy (habuf, &swaddr, sizeof swaddr);
90 /* Combine the subnet address and the host address. If
91 the host address is bigger than can fit in the subnet,
92 return a zero-length iaddr structure. */
94 j = rv.len - sizeof habuf;
95 for (i = sizeof habuf - 1; i >= 0; i--) {
96 if (mask.iabuf [i + j]) {
97 if (habuf [i] > (mask.iabuf [i + j] ^ 0xFF)) {
101 for (k = i - 1; k >= 0; k--) {
107 rv.iabuf [i + j] |= habuf [i];
110 rv.iabuf [i + j] = habuf [i];
116 /* Given a subnet number and netmask, return the address on that subnet
117 for which the host portion of the address is all ones (the standard
118 broadcast address). */
120 struct iaddr broadcast_addr (subnet, mask)
127 if (subnet.len != mask.len) {
132 for (i = 0; i < subnet.len; i++) {
133 rv.iabuf [i] = subnet.iabuf [i] | (~mask.iabuf [i] & 255);
140 u_int32_t host_addr (addr, mask)
150 /* Mask out the network bits... */
152 for (i = 0; i < rv.len; i++)
153 rv.iabuf [i] = addr.iabuf [i] & ~mask.iabuf [i];
155 /* Copy out up to 32 bits... */
156 memcpy (&swaddr, &rv.iabuf [rv.len - sizeof swaddr], sizeof swaddr);
158 /* Swap it and return it. */
159 return ntohl (swaddr);
162 int addr_eq (addr1, addr2)
163 struct iaddr addr1, addr2;
165 if (addr1.len != addr2.len)
167 return memcmp (addr1.iabuf, addr2.iabuf, addr1.len) == 0;
173 static char pbuf [4 * 16];
178 strcpy (s, "<null address>");
180 for (i = 0; i < addr.len; i++) {
181 sprintf (s, "%s%d", i ? "." : "", addr.iabuf [i]);
190 static char pbuf [4 * 16];
195 strcpy (s, "<null address>");
197 for (i = 0; i < addr.len; i++) {
198 sprintf (s, "%s%d", i ? "." : "", addr.iabuf [i]);
204 char *piaddrmask (struct iaddr addr, struct iaddr mask,
205 const char *file, int line)
211 for (i = 0; i < 32; i++) {
212 if (!mask.iabuf [3 - i / 8])
214 else if (mask.iabuf [3 - i / 8] & (1 << (i % 8)))
218 len = mw > 9 ? 2 : 1;
219 len += 4; /* three dots and a slash. */
220 for (i = 0; i < (mw / 8) + 1; i++) {
221 if (addr.iabuf [i] > 99)
223 else if (addr.iabuf [i] > 9)
228 s = dmalloc (len + 1, file, line);
232 sprintf (t, "%d", addr.iabuf [0]);
234 for (i = 1; i < (mw / 8) + 1; i++) {
235 sprintf (t, ".%d", addr.iabuf [i]);
239 sprintf (t, "%d", mw);