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
);