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