Sync with HEAD.
[dragonfly.git] / contrib / dhcp-3.0 / common / inet.c
blob53f5869ff4a9fd5e5aa735fb0999c50b29047598
1 /* inet.c
3 Subroutines to manipulate internet addresses in a safely portable
4 way... */
6 /*
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.
23 * 950 Charter Street
24 * Redwood City, CA 94063
25 * <info@isc.org>
26 * http://www.isc.org/
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''.
36 #ifndef lint
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";
39 #endif /* not lint */
41 #include "dhcpd.h"
43 /* Return just the network number of an internet address... */
45 struct iaddr subnet_number (addr, mask)
46 struct iaddr addr;
47 struct iaddr mask;
49 int i;
50 struct iaddr rv;
52 rv.len = 0;
54 /* Both addresses must have the same length... */
55 if (addr.len != mask.len)
56 return rv;
58 rv.len = addr.len;
59 for (i = 0; i < rv.len; i++)
60 rv.iabuf [i] = addr.iabuf [i] & mask.iabuf [i];
61 return rv;
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)
69 struct iaddr subnet;
70 struct iaddr mask;
71 u_int32_t host_address;
73 int i, j, k;
74 u_int32_t swaddr;
75 struct iaddr rv;
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. */
84 rv = subnet;
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)) {
89 rv.len = 0;
90 return rv;
92 for (k = i - 1; k >= 0; k--) {
93 if (habuf [k]) {
94 rv.len = 0;
95 return rv;
98 rv.iabuf [i + j] |= habuf [i];
99 break;
100 } else
101 rv.iabuf [i + j] = habuf [i];
104 return rv;
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)
112 struct iaddr subnet;
113 struct iaddr mask;
115 int i, j, k;
116 struct iaddr rv;
118 if (subnet.len != mask.len) {
119 rv.len = 0;
120 return rv;
123 for (i = 0; i < subnet.len; i++) {
124 rv.iabuf [i] = subnet.iabuf [i] | (~mask.iabuf [i] & 255);
126 rv.len = subnet.len;
128 return rv;
131 u_int32_t host_addr (addr, mask)
132 struct iaddr addr;
133 struct iaddr mask;
135 int i;
136 u_int32_t swaddr;
137 struct iaddr rv;
139 rv.len = 0;
141 /* Mask out the network bits... */
142 rv.len = addr.len;
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)
157 return 0;
158 return memcmp (addr1.iabuf, addr2.iabuf, addr1.len) == 0;
161 char *piaddr (addr)
162 struct iaddr addr;
164 static char pbuf [4 * 16];
165 char *s = pbuf;
166 int i;
168 if (addr.len == 0) {
169 strcpy (s, "<null address>");
171 for (i = 0; i < addr.len; i++) {
172 sprintf (s, "%s%d", i ? "." : "", addr.iabuf [i]);
173 s += strlen (s);
175 return pbuf;
178 char *piaddr1 (addr)
179 struct iaddr addr;
181 static char pbuf [4 * 16];
182 char *s = pbuf;
183 int i;
185 if (addr.len == 0) {
186 strcpy (s, "<null address>");
188 for (i = 0; i < addr.len; i++) {
189 sprintf (s, "%s%d", i ? "." : "", addr.iabuf [i]);
190 s += strlen (s);
192 return pbuf;
195 char *piaddrmask (struct iaddr addr, struct iaddr mask,
196 const char *file, int line)
198 char *s, *t;
199 int i, mw;
200 unsigned len;
202 for (i = 0; i < 32; i++) {
203 if (!mask.iabuf [3 - i / 8])
204 i += 7;
205 else if (mask.iabuf [3 - i / 8] & (1 << (i % 8)))
206 break;
208 mw = 32 - i;
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)
213 len += 3;
214 else if (addr.iabuf [i] > 9)
215 len += 2;
216 else
217 len++;
219 s = dmalloc (len + 1, file, line);
220 if (!s)
221 return s;
222 t = s;
223 sprintf (t, "%d", addr.iabuf [0]);
224 t += strlen (t);
225 for (i = 1; i < (mw / 8) + 1; i++) {
226 sprintf (t, ".%d", addr.iabuf [i]);
227 t += strlen (t);
229 *t++ = '/';
230 sprintf (t, "%d", mw);
231 return s;