1*837cddffSkrw /* $OpenBSD: inet.c,v 1.6 2016/02/06 23:50:10 krw Exp $ */
2e853bc5dShenning
3c824f21bShenning /*
4c824f21bShenning * Subroutines to manipulate internet addresses in a safely portable
5c824f21bShenning * way...
6c824f21bShenning */
7e853bc5dShenning
8e853bc5dShenning /*
9e853bc5dShenning * Copyright (c) 1996 The Internet Software Consortium. All rights reserved.
10e853bc5dShenning *
11e853bc5dShenning * Redistribution and use in source and binary forms, with or without
12e853bc5dShenning * modification, are permitted provided that the following conditions
13e853bc5dShenning * are met:
14e853bc5dShenning *
15e853bc5dShenning * 1. Redistributions of source code must retain the above copyright
16e853bc5dShenning * notice, this list of conditions and the following disclaimer.
17e853bc5dShenning * 2. Redistributions in binary form must reproduce the above copyright
18e853bc5dShenning * notice, this list of conditions and the following disclaimer in the
19e853bc5dShenning * documentation and/or other materials provided with the distribution.
20e853bc5dShenning * 3. Neither the name of The Internet Software Consortium nor the names
21e853bc5dShenning * of its contributors may be used to endorse or promote products derived
22e853bc5dShenning * from this software without specific prior written permission.
23e853bc5dShenning *
24e853bc5dShenning * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
25e853bc5dShenning * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
26e853bc5dShenning * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27e853bc5dShenning * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28e853bc5dShenning * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
29e853bc5dShenning * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30e853bc5dShenning * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31e853bc5dShenning * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
32e853bc5dShenning * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33e853bc5dShenning * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34e853bc5dShenning * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
35e853bc5dShenning * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36e853bc5dShenning * SUCH DAMAGE.
37e853bc5dShenning *
38e853bc5dShenning * This software has been written for the Internet Software Consortium
39e853bc5dShenning * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
40e853bc5dShenning * Enterprises. To learn more about the Internet Software Consortium,
41e853bc5dShenning * see ``http://www.vix.com/isc''. To learn more about Vixie
42e853bc5dShenning * Enterprises, see ``http://www.vix.com''.
43e853bc5dShenning */
44e853bc5dShenning
45*837cddffSkrw #include <sys/types.h>
46*837cddffSkrw #include <sys/socket.h>
47*837cddffSkrw
48*837cddffSkrw #include <arpa/inet.h>
49*837cddffSkrw
50*837cddffSkrw #include <net/if.h>
51*837cddffSkrw
52*837cddffSkrw #include <netinet/in.h>
53*837cddffSkrw
54*837cddffSkrw #include <stdio.h>
55*837cddffSkrw #include <string.h>
56*837cddffSkrw
57*837cddffSkrw #include "dhcp.h"
58*837cddffSkrw #include "tree.h"
59e853bc5dShenning #include "dhcpd.h"
60e853bc5dShenning
61c824f21bShenning /*
62c824f21bShenning * Return just the network number of an internet address...
63c824f21bShenning */
64c824f21bShenning struct iaddr
subnet_number(struct iaddr addr,struct iaddr mask)65c824f21bShenning subnet_number(struct iaddr addr, struct iaddr mask)
66e853bc5dShenning {
67e853bc5dShenning struct iaddr rv;
68c824f21bShenning int i;
69e853bc5dShenning
70e853bc5dShenning rv.len = 0;
71e853bc5dShenning
72e853bc5dShenning /* Both addresses must have the same length... */
73e853bc5dShenning if (addr.len != mask.len)
74c824f21bShenning return (rv);
75e853bc5dShenning
76e853bc5dShenning rv.len = addr.len;
77e853bc5dShenning for (i = 0; i < rv.len; i++)
78e853bc5dShenning rv.iabuf[i] = addr.iabuf[i] & mask.iabuf[i];
79c824f21bShenning return (rv);
80e853bc5dShenning }
81e853bc5dShenning
82c824f21bShenning /*
83c824f21bShenning * Combine a network number and a integer to produce an internet address.
84e853bc5dShenning * This won't work for subnets with more than 32 bits of host address, but
85e853bc5dShenning * maybe this isn't a problem.
86e853bc5dShenning */
87c824f21bShenning struct iaddr
ip_addr(struct iaddr subnet,struct iaddr mask,u_int32_t host_address)88c824f21bShenning ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
89e853bc5dShenning {
90e853bc5dShenning int i, j, k;
91e853bc5dShenning u_int32_t swaddr;
92c824f21bShenning unsigned char habuf[sizeof(swaddr)];
93e853bc5dShenning struct iaddr rv;
94e853bc5dShenning
95e853bc5dShenning swaddr = htonl(host_address);
96c824f21bShenning memcpy(habuf, &swaddr, sizeof(swaddr));
97e853bc5dShenning
98c824f21bShenning /*
99c824f21bShenning * Combine the subnet address and the host address. If the
100c824f21bShenning * host address is bigger than can fit in the subnet, return a
101c824f21bShenning * zero-length iaddr structure.
102c824f21bShenning */
103e853bc5dShenning rv = subnet;
104c824f21bShenning j = rv.len - sizeof(habuf);
105c824f21bShenning for (i = sizeof(habuf) - 1; i >= 0; i--) {
106e853bc5dShenning if (mask.iabuf[i + j]) {
107e853bc5dShenning if (habuf[i] > (mask.iabuf[i + j] ^ 0xFF)) {
108e853bc5dShenning rv.len = 0;
109c824f21bShenning return (rv);
110e853bc5dShenning }
111c824f21bShenning for (k = i - 1; k >= 0; k--)
112e853bc5dShenning if (habuf[k]) {
113e853bc5dShenning rv.len = 0;
114c824f21bShenning return (rv);
115e853bc5dShenning }
116e853bc5dShenning rv.iabuf[i + j] |= habuf[i];
117e853bc5dShenning break;
118e853bc5dShenning } else
119e853bc5dShenning rv.iabuf[i + j] = habuf[i];
120e853bc5dShenning }
121e853bc5dShenning
122c824f21bShenning return (rv);
123e853bc5dShenning }
124e853bc5dShenning
125c824f21bShenning u_int32_t
host_addr(struct iaddr addr,struct iaddr mask)126c824f21bShenning host_addr(struct iaddr addr, struct iaddr mask)
127e853bc5dShenning {
128e853bc5dShenning int i;
129e853bc5dShenning u_int32_t swaddr;
130e853bc5dShenning struct iaddr rv;
131e853bc5dShenning
132e853bc5dShenning rv.len = 0;
133e853bc5dShenning
134e853bc5dShenning /* Mask out the network bits... */
135e853bc5dShenning rv.len = addr.len;
136e853bc5dShenning for (i = 0; i < rv.len; i++)
137e853bc5dShenning rv.iabuf[i] = addr.iabuf[i] & ~mask.iabuf[i];
138e853bc5dShenning
139e853bc5dShenning /* Copy out up to 32 bits... */
140c824f21bShenning memcpy(&swaddr, &rv.iabuf[rv.len - sizeof(swaddr)], sizeof(swaddr));
141e853bc5dShenning
142e853bc5dShenning /* Swap it and return it. */
143c824f21bShenning return (ntohl(swaddr));
144e853bc5dShenning }
145e853bc5dShenning
146c824f21bShenning int
addr_eq(struct iaddr addr1,struct iaddr addr2)147c824f21bShenning addr_eq(struct iaddr addr1, struct iaddr addr2)
148e853bc5dShenning {
149e853bc5dShenning if (addr1.len != addr2.len)
150c824f21bShenning return (0);
151c824f21bShenning return (memcmp(addr1.iabuf, addr2.iabuf, addr1.len) == 0);
152e853bc5dShenning }
153e853bc5dShenning
154ea507cabSderaadt char *
piaddr(struct iaddr addr)155ea507cabSderaadt piaddr(struct iaddr addr)
156e853bc5dShenning {
157e853bc5dShenning static char pbuf[32];
158a53ae031Sclaudio const char *s;
159e853bc5dShenning
160c824f21bShenning if (addr.len == 0)
161e853bc5dShenning strlcpy(pbuf, "<null address>", sizeof(pbuf));
162e853bc5dShenning else {
163a53ae031Sclaudio s = inet_ntop(AF_INET, &addr.iabuf, pbuf, sizeof pbuf);
164a53ae031Sclaudio if (s == NULL)
165e853bc5dShenning strlcpy(pbuf, "<invalid address>", sizeof(pbuf));
166e853bc5dShenning }
167e853bc5dShenning return (pbuf);
168e853bc5dShenning }
169