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