1 /* inet.c
2
3 Subroutines to manipulate internet addresses and ports in a safely portable
4 way... */
5
6 /*
7 * Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 1995-2003 by Internet Software Consortium
9 *
10 * This Source Code Form is subject to the terms of the Mozilla Public
11 * License, v. 2.0. If a copy of the MPL was not distributed with this
12 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
13 *
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.
21 *
22 * Internet Systems Consortium, Inc.
23 * 950 Charter Street
24 * Redwood City, CA 94063
25 * <info@isc.org>
26 * https://www.isc.org/
27 *
28 */
29
30 #include "dhcpd.h"
31
32 /* Return just the network number of an internet address... */
33
subnet_number(addr,mask)34 struct iaddr subnet_number (addr, mask)
35 struct iaddr addr;
36 struct iaddr mask;
37 {
38 int i;
39 struct iaddr rv;
40
41 if (addr.len > sizeof(addr.iabuf))
42 log_fatal("subnet_number():%s:%d: Invalid addr length.", MDL);
43 if (addr.len != mask.len)
44 log_fatal("subnet_number():%s:%d: Addr/mask length mismatch.",
45 MDL);
46
47 rv.len = 0;
48
49 /* Both addresses must have the same length... */
50 if (addr.len != mask.len)
51 return rv;
52
53 rv.len = addr.len;
54 for (i = 0; i < rv.len; i++)
55 rv.iabuf [i] = addr.iabuf [i] & mask.iabuf [i];
56 return rv;
57 }
58
59 /* Combine a network number and a integer to produce an internet address.
60 This won't work for subnets with more than 32 bits of host address, but
61 maybe this isn't a problem. */
62
ip_addr(subnet,mask,host_address)63 struct iaddr ip_addr (subnet, mask, host_address)
64 struct iaddr subnet;
65 struct iaddr mask;
66 u_int32_t host_address;
67 {
68 int i, j, k;
69 u_int32_t swaddr;
70 struct iaddr rv;
71 unsigned char habuf [sizeof swaddr];
72
73 if (subnet.len > sizeof(subnet.iabuf))
74 log_fatal("ip_addr():%s:%d: Invalid addr length.", MDL);
75 if (subnet.len != mask.len)
76 log_fatal("ip_addr():%s:%d: Addr/mask length mismatch.",
77 MDL);
78
79 swaddr = htonl (host_address);
80 memcpy (habuf, &swaddr, sizeof swaddr);
81
82 /* Combine the subnet address and the host address. If
83 the host address is bigger than can fit in the subnet,
84 return a zero-length iaddr structure. */
85 rv = subnet;
86 j = rv.len - sizeof habuf;
87 for (i = sizeof habuf - 1; i >= 0; i--) {
88 if (mask.iabuf [i + j]) {
89 if (habuf [i] > (mask.iabuf [i + j] ^ 0xFF)) {
90 rv.len = 0;
91 return rv;
92 }
93 for (k = i - 1; k >= 0; k--) {
94 if (habuf [k]) {
95 rv.len = 0;
96 return rv;
97 }
98 }
99 rv.iabuf [i + j] |= habuf [i];
100 break;
101 } else
102 rv.iabuf [i + j] = habuf [i];
103 }
104
105 return rv;
106 }
107
108 /* Given a subnet number and netmask, return the address on that subnet
109 for which the host portion of the address is all ones (the standard
110 broadcast address). */
111
broadcast_addr(subnet,mask)112 struct iaddr broadcast_addr (subnet, mask)
113 struct iaddr subnet;
114 struct iaddr mask;
115 {
116 int i;
117 struct iaddr rv;
118
119 if (subnet.len > sizeof(subnet.iabuf))
120 log_fatal("broadcast_addr():%s:%d: Invalid addr length.", MDL);
121 if (subnet.len != mask.len)
122 log_fatal("broadcast_addr():%s:%d: Addr/mask length mismatch.",
123 MDL);
124
125 if (subnet.len != mask.len) {
126 rv.len = 0;
127 return rv;
128 }
129
130 for (i = 0; i < subnet.len; i++) {
131 rv.iabuf [i] = subnet.iabuf [i] | (~mask.iabuf [i] & 255);
132 }
133 rv.len = subnet.len;
134
135 return rv;
136 }
137
host_addr(addr,mask)138 u_int32_t host_addr (addr, mask)
139 struct iaddr addr;
140 struct iaddr mask;
141 {
142 int i;
143 u_int32_t swaddr;
144 struct iaddr rv;
145
146 if (addr.len > sizeof(addr.iabuf))
147 log_fatal("host_addr():%s:%d: Invalid addr length.", MDL);
148 if (addr.len != mask.len)
149 log_fatal("host_addr():%s:%d: Addr/mask length mismatch.",
150 MDL);
151
152 rv.len = 0;
153
154 /* Mask out the network bits... */
155 rv.len = addr.len;
156 for (i = 0; i < rv.len; i++)
157 rv.iabuf [i] = addr.iabuf [i] & ~mask.iabuf [i];
158
159 /* Copy out up to 32 bits... */
160 memcpy (&swaddr, &rv.iabuf [rv.len - sizeof swaddr], sizeof swaddr);
161
162 /* Swap it and return it. */
163 return ntohl (swaddr);
164 }
165
addr_eq(addr1,addr2)166 int addr_eq (addr1, addr2)
167 struct iaddr addr1, addr2;
168 {
169 if (addr1.len > sizeof(addr1.iabuf))
170 log_fatal("addr_eq():%s:%d: Invalid addr length.", MDL);
171
172 if (addr1.len != addr2.len)
173 return 0;
174 return memcmp (addr1.iabuf, addr2.iabuf, addr1.len) == 0;
175 }
176
177 /* addr_match
178 *
179 * compares an IP address against a network/mask combination
180 * by ANDing the IP with the mask and seeing whether the result
181 * matches the masked network value.
182 */
183 int
addr_match(addr,match)184 addr_match(addr, match)
185 struct iaddr *addr;
186 struct iaddrmatch *match;
187 {
188 int i;
189
190 if (addr->len != match->addr.len)
191 return 0;
192
193 for (i = 0 ; i < addr->len ; i++) {
194 if ((addr->iabuf[i] & match->mask.iabuf[i]) !=
195 match->addr.iabuf[i])
196 return 0;
197 }
198 return 1;
199 }
200
201 /*
202 * Compares the addresses a1 and a2.
203 *
204 * If a1 < a2, returns -1.
205 * If a1 == a2, returns 0.
206 * If a1 > a2, returns 1.
207 *
208 * WARNING: if a1 and a2 differ in length, returns 0.
209 */
210 int
addr_cmp(const struct iaddr * a1,const struct iaddr * a2)211 addr_cmp(const struct iaddr *a1, const struct iaddr *a2) {
212 int i;
213
214 if (a1->len != a2->len) {
215 return 0;
216 }
217
218 for (i=0; i<a1->len; i++) {
219 if (a1->iabuf[i] < a2->iabuf[i]) {
220 return -1;
221 }
222 if (a1->iabuf[i] > a2->iabuf[i]) {
223 return 1;
224 }
225 }
226
227 return 0;
228 }
229
230 /*
231 * Performs a bitwise-OR of two addresses.
232 *
233 * Returns 1 if the result is non-zero, or 0 otherwise.
234 *
235 * WARNING: if a1 and a2 differ in length, returns 0.
236 */
237 int
addr_or(struct iaddr * result,const struct iaddr * a1,const struct iaddr * a2)238 addr_or(struct iaddr *result, const struct iaddr *a1, const struct iaddr *a2) {
239 int i;
240 int all_zero;
241
242 if (a1->len != a2->len) {
243 return 0;
244 }
245
246 all_zero = 1;
247
248 result->len = a1->len;
249 for (i=0; i<a1->len; i++) {
250 result->iabuf[i] = a1->iabuf[i] | a2->iabuf[i];
251 if (result->iabuf[i] != 0) {
252 all_zero = 0;
253 }
254 }
255
256 return !all_zero;
257 }
258
259 /*
260 * Performs a bitwise-AND of two addresses.
261 *
262 * Returns 1 if the result is non-zero, or 0 otherwise.
263 *
264 * WARNING: if a1 and a2 differ in length, returns 0.
265 */
266 int
addr_and(struct iaddr * result,const struct iaddr * a1,const struct iaddr * a2)267 addr_and(struct iaddr *result, const struct iaddr *a1, const struct iaddr *a2) {
268 int i;
269 int all_zero;
270
271 if (a1->len != a2->len) {
272 return 0;
273 }
274
275 all_zero = 1;
276
277 result->len = a1->len;
278 for (i=0; i<a1->len; i++) {
279 result->iabuf[i] = a1->iabuf[i] & a2->iabuf[i];
280 if (result->iabuf[i] != 0) {
281 all_zero = 0;
282 }
283 }
284
285 return !all_zero;
286 }
287
288 /*
289 * Check if a bitmask of the given length is valid for the address.
290 * This is not the case if any bits longer than the bitmask are 1.
291 *
292 * So, this is valid:
293 *
294 * 127.0.0.0/8
295 *
296 * But this is not:
297 *
298 * 127.0.0.1/8
299 *
300 * Because the final ".1" would get masked out by the /8.
301 */
302 isc_boolean_t
is_cidr_mask_valid(const struct iaddr * addr,int bits)303 is_cidr_mask_valid(const struct iaddr *addr, int bits) {
304 int zero_bits;
305 int zero_bytes;
306 int i;
307 char byte;
308 int shift_bits;
309
310 /*
311 * Check our bit boundaries.
312 */
313 if (bits < 0) {
314 return ISC_FALSE;
315 }
316 if (bits > (addr->len * 8)) {
317 return ISC_FALSE;
318 }
319
320 /*
321 * Figure out how many low-order bits need to be zero.
322 */
323 zero_bits = (addr->len * 8) - bits;
324 zero_bytes = zero_bits / 8;
325
326 /*
327 * Check to make sure the low-order bytes are zero.
328 */
329 for (i=1; i<=zero_bytes; i++) {
330 if (addr->iabuf[addr->len-i] != 0) {
331 return ISC_FALSE;
332 }
333 }
334
335 /*
336 * Look to see if any bits not in right-hand bytes are
337 * non-zero, by making a byte that has these bits set to zero
338 * comparing to the original byte. If these two values are
339 * equal, then the right-hand bits are zero, and we are
340 * happy.
341 */
342 shift_bits = zero_bits % 8;
343 if (shift_bits == 0) return ISC_TRUE;
344 byte = addr->iabuf[addr->len-zero_bytes-1];
345 return (((byte >> shift_bits) << shift_bits) == byte);
346 }
347
348 /*
349 * range2cidr
350 *
351 * Converts a range of IP addresses to a set of CIDR networks.
352 *
353 * Examples:
354 * 192.168.0.0 - 192.168.0.255 = 192.168.0.0/24
355 * 10.0.0.0 - 10.0.1.127 = 10.0.0.0/24, 10.0.1.0/25
356 * 255.255.255.32 - 255.255.255.255 = 255.255.255.32/27, 255.255.255.64/26,
357 * 255.255.255.128/25
358 */
359 isc_result_t
range2cidr(struct iaddrcidrnetlist ** result,const struct iaddr * lo,const struct iaddr * hi)360 range2cidr(struct iaddrcidrnetlist **result,
361 const struct iaddr *lo, const struct iaddr *hi) {
362 struct iaddr addr;
363 struct iaddr mask;
364 int bit;
365 struct iaddr end_addr;
366 struct iaddr dummy;
367 int ofs, val;
368 struct iaddrcidrnetlist *net;
369 int tmp;
370
371 if (result == NULL) {
372 return DHCP_R_INVALIDARG;
373 }
374 if (*result != NULL) {
375 return DHCP_R_INVALIDARG;
376 }
377 if ((lo == NULL) || (hi == NULL) || (lo->len != hi->len)) {
378 return DHCP_R_INVALIDARG;
379 }
380
381 /*
382 * Put our start and end in the right order, if reversed.
383 */
384 if (addr_cmp(lo, hi) > 0) {
385 const struct iaddr *tmp;
386 tmp = lo;
387 lo = hi;
388 hi = tmp;
389 }
390
391 /*
392 * Theory of operation:
393 *
394 * -------------------
395 * Start at the low end, and keep trying larger networks
396 * until we get one that is too big (explained below).
397 *
398 * We keep a "mask", which is the ones-complement of a
399 * normal netmask. So, a /23 has a netmask of 255.255.254.0,
400 * and a mask of 0.0.1.255.
401 *
402 * We know when a network is too big when we bitwise-AND the
403 * mask with the starting address and we get a non-zero
404 * result, like this:
405 *
406 * addr: 192.168.1.0, mask: 0.0.1.255
407 * bitwise-AND: 0.0.1.0
408 *
409 * A network is also too big if the bitwise-OR of the mask
410 * with the starting address is larger than the end address,
411 * like this:
412 *
413 * start: 192.168.1.0, mask: 0.0.1.255, end: 192.168.0.255
414 * bitwise-OR: 192.168.1.255
415 *
416 * -------------------
417 * Once we have found a network that is too big, we add the
418 * appropriate CIDR network to our list of found networks.
419 *
420 * We then use the next IP address as our low address, and
421 * begin the process of searching for a network that is
422 * too big again, starting with an empty mask.
423 */
424 addr = *lo;
425 bit = 0;
426 memset(&mask, 0, sizeof(mask));
427 mask.len = addr.len;
428 while (addr_cmp(&addr, hi) <= 0) {
429 /*
430 * Bitwise-OR mask with (1 << bit)
431 */
432 ofs = addr.len - (bit / 8) - 1;
433 val = 1 << (bit % 8);
434 if (ofs >= 0) {
435 mask.iabuf[ofs] |= val;
436 }
437
438 /*
439 * See if we're too big, and save this network if so.
440 */
441 addr_or(&end_addr, &addr, &mask);
442 if ((ofs < 0) ||
443 (addr_cmp(&end_addr, hi) > 0) ||
444 addr_and(&dummy, &addr, &mask)) {
445 /*
446 * Add a new prefix to our list.
447 */
448 net = dmalloc(sizeof(*net), MDL);
449 if (net == NULL) {
450 while (*result != NULL) {
451 net = (*result)->next;
452 dfree(*result, MDL);
453 *result = net;
454 }
455 return ISC_R_NOMEMORY;
456 }
457 net->cidrnet.lo_addr = addr;
458 net->cidrnet.bits = (addr.len * 8) - bit;
459 net->next = *result;
460 *result = net;
461
462 /*
463 * Figure out our new starting address,
464 * by adding (1 << bit) to our previous
465 * starting address.
466 */
467 tmp = addr.iabuf[ofs] + val;
468 while ((ofs >= 0) && (tmp > 255)) {
469 addr.iabuf[ofs] = tmp - 256;
470 ofs--;
471 tmp = addr.iabuf[ofs] + 1;
472 }
473 if (ofs < 0) {
474 /* Gone past last address, we're done. */
475 break;
476 }
477 addr.iabuf[ofs] = tmp;
478
479 /*
480 * Reset our bit and mask.
481 */
482 bit = 0;
483 memset(mask.iabuf, 0, sizeof(mask.iabuf));
484 memset(end_addr.iabuf, 0, sizeof(end_addr.iabuf));
485 } else {
486 /*
487 * If we're not too big, increase our network size.
488 */
489 bit++;
490 }
491 }
492
493 /*
494 * We're done.
495 */
496 return ISC_R_SUCCESS;
497 }
498
499 /*
500 * Free a list of CIDR networks, such as returned from range2cidr().
501 */
502 isc_result_t
free_iaddrcidrnetlist(struct iaddrcidrnetlist ** result)503 free_iaddrcidrnetlist(struct iaddrcidrnetlist **result) {
504 struct iaddrcidrnetlist *p;
505
506 if (result == NULL) {
507 return DHCP_R_INVALIDARG;
508 }
509 if (*result == NULL) {
510 return DHCP_R_INVALIDARG;
511 }
512
513 while (*result != NULL) {
514 p = *result;
515 *result = p->next;
516 dfree(p, MDL);
517 }
518
519 return ISC_R_SUCCESS;
520 }
521
522 /* piaddr() turns an iaddr structure into a printable address. */
523 /* XXX: should use a const pointer rather than passing the structure */
524 const char *
piaddr(const struct iaddr addr)525 piaddr(const struct iaddr addr) {
526 static char
527 pbuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
528 /* "255.255.255.255" */
529
530 /* INSIST((addr.len == 0) || (addr.len == 4) || (addr.len == 16)); */
531
532 if (addr.len == 0) {
533 return "<null address>";
534 }
535 if (addr.len == 4) {
536 return inet_ntop(AF_INET, addr.iabuf, pbuf, sizeof(pbuf));
537 }
538 if (addr.len == 16) {
539 return inet_ntop(AF_INET6, addr.iabuf, pbuf, sizeof(pbuf));
540 }
541
542 log_fatal("piaddr():%s:%d: Invalid address length %d.", MDL,
543 addr.len);
544 /* quell compiler warnings */
545 return NULL;
546 }
547
548 /* piaddrmask takes an iaddr structure mask, determines the bitlength of
549 * the mask, and then returns the printable CIDR notation of the two.
550 */
551 char *
piaddrmask(struct iaddr * addr,struct iaddr * mask)552 piaddrmask(struct iaddr *addr, struct iaddr *mask) {
553 int mw;
554 unsigned int oct, bit;
555
556 if ((addr->len != 4) && (addr->len != 16))
557 log_fatal("piaddrmask():%s:%d: Address length %d invalid",
558 MDL, addr->len);
559 if (addr->len != mask->len)
560 log_fatal("piaddrmask():%s:%d: Address and mask size mismatch",
561 MDL);
562
563 /* Determine netmask width in bits. */
564 for (mw = (mask->len * 8) ; mw > 0 ; ) {
565 oct = (mw - 1) / 8;
566 bit = 0x80 >> ((mw - 1) % 8);
567 if (!mask->iabuf[oct])
568 mw -= 8;
569 else if (mask->iabuf[oct] & bit)
570 break;
571 else
572 mw--;
573 }
574
575 if (mw < 0)
576 log_fatal("Impossible condition at %s:%d.", MDL);
577
578 return piaddrcidr(addr, mw);
579 }
580
581 /* Format an address and mask-length into printable CIDR notation. */
582 char *
piaddrcidr(const struct iaddr * addr,unsigned int bits)583 piaddrcidr(const struct iaddr *addr, unsigned int bits) {
584 static char
585 ret[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128")];
586 /* "255.255.255.255/32" */
587
588 /* INSIST(addr != NULL); */
589 /* INSIST((addr->len == 4) || (addr->len == 16)); */
590 /* INSIST(bits <= (addr->len * 8)); */
591
592 if (bits > (addr->len * 8))
593 return NULL;
594
595 sprintf(ret, "%s/%d", piaddr(*addr), bits);
596
597 return ret;
598 }
599
600 /* Validate that the string represents a valid port number and
601 * return it in network byte order
602 */
603
604 u_int16_t
validate_port(char * port)605 validate_port(char *port) {
606 long local_port = 0;
607 long lower = 1;
608 long upper = 65535;
609 char *endptr;
610
611 errno = 0;
612 local_port = strtol(port, &endptr, 10);
613
614 if ((*endptr != '\0') || (errno == ERANGE) || (errno == EINVAL))
615 log_fatal ("Invalid port number specification: %s", port);
616
617 if (local_port < lower || local_port > upper)
618 log_fatal("Port number specified is out of range (%ld-%ld).",
619 lower, upper);
620
621 return htons((u_int16_t)local_port);
622 }
623
624 /* \brief Validate that the string represents a valid port pair (i.e. n,n+1)
625 *
626 * \param the string to validate
627 * \return the first port number in network byte order
628 */
629
630 u_int16_t
validate_port_pair(char * port)631 validate_port_pair(char *port) {
632 long local_port = 0;
633 long lower = 1;
634 long upper = 65534;
635 char *endptr;
636
637 errno = 0;
638 local_port = strtol(port, &endptr, 10);
639
640 if ((*endptr != '\0') || (errno == ERANGE) || (errno == EINVAL))
641 log_fatal ("Invalid port pair specification: %s", port);
642
643 if (local_port < lower || local_port > upper)
644 log_fatal("Port pair specified is out of range (%ld-%ld).",
645 lower, upper);
646
647 return htons((u_int16_t)local_port);
648 }
649
650 #ifdef DHCPv6
651 /* Print a v6 address from an in6_addr struct */
652 const char *
pin6_addr(const struct in6_addr * src)653 pin6_addr(const struct in6_addr *src){
654
655 if (!src) {
656 return ("<null>");
657 }
658
659 struct iaddr addr;
660 addr.len = 16;
661 memcpy(addr.iabuf, src->s6_addr, 16);
662 return (piaddr(addr));
663 }
664 #endif
665