ISC DHCP  4.4.1
A reference DHCPv4 and DHCPv6 implementation
inet.c
Go to the documentation of this file.
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 
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 
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 
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 
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 
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
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
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
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
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
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
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
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 static const char *
523 inet_ntopdd(const unsigned char *src, unsigned srclen, char *dst, size_t size)
524 {
525  char tmp[sizeof("32.255.255.255.255")];
526  int len;
527 
528  switch (srclen) {
529  case 2:
530  len = sprintf (tmp, "%u.%u", src[0], src[1]);
531  break;
532  case 3:
533  len = sprintf (tmp, "%u.%u.%u", src[0], src[1], src[2]);
534  break;
535  case 4:
536  len = sprintf (tmp, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]);
537  break;
538  case 5:
539  len = sprintf (tmp, "%u.%u.%u.%u.%u", src[0], src[1], src[2], src[3], src[4]);
540  break;
541  default:
542  return NULL;
543  }
544  if (len < 0)
545  return NULL;
546 
547  if (len > size) {
548  errno = ENOSPC;
549  return NULL;
550  }
551 
552  return strcpy (dst, tmp);
553 }
554 
555 /* pdestdesc() turns an iaddr structure into a printable dest. descriptor */
556 const char *
557 pdestdesc(const struct iaddr addr) {
558  static char pbuf[sizeof("255.255.255.255.255")];
559 
560  if (addr.len == 0) {
561  return "<null destination descriptor>";
562  }
563  if (addr.len == 1) {
564  return "0";
565  }
566  if ((addr.len >= 2) && (addr.len <= 5)) {
567  return inet_ntopdd(addr.iabuf, addr.len, pbuf, sizeof(pbuf));
568  }
569 
570  log_fatal("pdestdesc():%s:%d: Invalid destination descriptor length %d.",
571  MDL, addr.len);
572  /* quell compiler warnings */
573  return NULL;
574 }
575 
576 /* piaddr() turns an iaddr structure into a printable address. */
577 /* XXX: should use a const pointer rather than passing the structure */
578 const char *
579 piaddr(const struct iaddr addr) {
580  static char
581  pbuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
582  /* "255.255.255.255" */
583 
584  /* INSIST((addr.len == 0) || (addr.len == 4) || (addr.len == 16)); */
585 
586  if (addr.len == 0) {
587  return "<null address>";
588  }
589  if (addr.len == 4) {
590  return inet_ntop(AF_INET, addr.iabuf, pbuf, sizeof(pbuf));
591  }
592  if (addr.len == 16) {
593  return inet_ntop(AF_INET6, addr.iabuf, pbuf, sizeof(pbuf));
594  }
595 
596  log_fatal("piaddr():%s:%d: Invalid address length %d.", MDL,
597  addr.len);
598  /* quell compiler warnings */
599  return NULL;
600 }
601 
602 /* piaddrmask takes an iaddr structure mask, determines the bitlength of
603  * the mask, and then returns the printable CIDR notation of the two.
604  */
605 char *
606 piaddrmask(struct iaddr *addr, struct iaddr *mask) {
607  int mw;
608  unsigned int oct, bit;
609 
610  if ((addr->len != 4) && (addr->len != 16))
611  log_fatal("piaddrmask():%s:%d: Address length %d invalid",
612  MDL, addr->len);
613  if (addr->len != mask->len)
614  log_fatal("piaddrmask():%s:%d: Address and mask size mismatch",
615  MDL);
616 
617  /* Determine netmask width in bits. */
618  for (mw = (mask->len * 8) ; mw > 0 ; ) {
619  oct = (mw - 1) / 8;
620  bit = 0x80 >> ((mw - 1) % 8);
621  if (!mask->iabuf[oct])
622  mw -= 8;
623  else if (mask->iabuf[oct] & bit)
624  break;
625  else
626  mw--;
627  }
628 
629  if (mw < 0)
630  log_fatal("Impossible condition at %s:%d.", MDL);
631 
632  return piaddrcidr(addr, mw);
633 }
634 
635 /* Format an address and mask-length into printable CIDR notation. */
636 char *
637 piaddrcidr(const struct iaddr *addr, unsigned int bits) {
638  static char
639  ret[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128")];
640  /* "255.255.255.255/32" */
641 
642  /* INSIST(addr != NULL); */
643  /* INSIST((addr->len == 4) || (addr->len == 16)); */
644  /* INSIST(bits <= (addr->len * 8)); */
645 
646  if (bits > (addr->len * 8))
647  return NULL;
648 
649  sprintf(ret, "%s/%d", piaddr(*addr), bits);
650 
651  return ret;
652 }
653 
654 /* Validate that the string represents a valid port number and
655  * return it in network byte order
656  */
657 
658 u_int16_t
659 validate_port(char *port) {
660  long local_port = 0;
661  long lower = 1;
662  long upper = 65535;
663  char *endptr;
664 
665  errno = 0;
666  local_port = strtol(port, &endptr, 10);
667 
668  if ((*endptr != '\0') || (errno == ERANGE) || (errno == EINVAL))
669  log_fatal ("Invalid port number specification: %s", port);
670 
671  if (local_port < lower || local_port > upper)
672  log_fatal("Port number specified is out of range (%ld-%ld).",
673  lower, upper);
674 
675  return htons((u_int16_t)local_port);
676 }
677 
678 /* \brief Validate that the string represents a valid port pair (i.e. n,n+1)
679  *
680  * \param the string to validate
681  * \return the first port number in network byte order
682  */
683 
684 u_int16_t
685 validate_port_pair(char *port) {
686  long local_port = 0;
687  long lower = 1;
688  long upper = 65534;
689  char *endptr;
690 
691  errno = 0;
692  local_port = strtol(port, &endptr, 10);
693 
694  if ((*endptr != '\0') || (errno == ERANGE) || (errno == EINVAL))
695  log_fatal ("Invalid port pair specification: %s", port);
696 
697  if (local_port < lower || local_port > upper)
698  log_fatal("Port pair specified is out of range (%ld-%ld).",
699  lower, upper);
700 
701  return htons((u_int16_t)local_port);
702 }
703 
704 #ifdef DHCPv6
705 /* Print a v6 address from an in6_addr struct */
706 const char *
707 pin6_addr(const struct in6_addr *src){
708 
709  if (!src) {
710  return ("<null>");
711  }
712 
713  struct iaddr addr;
714  addr.len = 16;
715  memcpy(addr.iabuf, src->s6_addr, 16);
716  return (piaddr(addr));
717 }
718 #endif
struct iaddrcidrnet cidrnet
Definition: inet.h:77
int addr_or(struct iaddr *result, const struct iaddr *a1, const struct iaddr *a2)
Definition: inet.c:238
int bits
Definition: inet.h:72
const char * piaddr(const struct iaddr addr)
Definition: inet.c:579
char * piaddrmask(struct iaddr *addr, struct iaddr *mask)
Definition: inet.c:606
Definition: dhcpd.h:1061
int addr_cmp(const struct iaddr *a1, const struct iaddr *a2)
Definition: inet.c:211
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
Definition: inet.c:63
#define MDL
Definition: omapip.h:567
unsigned char iabuf[16]
Definition: inet.h:33
#define DHCP_R_INVALIDARG
Definition: result.h:48
unsigned len
Definition: inet.h:32
const char * pdestdesc(const struct iaddr addr)
Definition: inet.c:557
void log_fatal(const char *,...) __attribute__((__format__(__printf__
struct iaddr subnet_number(struct iaddr addr, struct iaddr mask)
Definition: inet.c:34
u_int16_t validate_port(char *port)
Definition: inet.c:659
u_int16_t local_port
Definition: dhclient.c:94
struct iaddrcidrnetlist * next
Definition: inet.h:76
isc_result_t free_iaddrcidrnetlist(struct iaddrcidrnetlist **result)
Definition: inet.c:503
void dfree(void *, const char *, int)
Definition: alloc.c:145
const char * pin6_addr(const struct in6_addr *)
u_int16_t validate_port_pair(char *port)
Definition: inet.c:685
void * dmalloc(size_t, const char *, int)
Definition: alloc.c:57
int addr_eq(struct iaddr addr1, struct iaddr addr2)
Definition: inet.c:166
struct iaddr broadcast_addr(struct iaddr subnet, struct iaddr mask)
Definition: inet.c:112
Definition: inet.h:31
u_int32_t host_addr(struct iaddr addr, struct iaddr mask)
Definition: inet.c:138
isc_boolean_t is_cidr_mask_valid(const struct iaddr *addr, int bits)
Definition: inet.c:303
int addr_match(struct iaddr *addr, struct iaddrmatch *match)
Definition: inet.c:184
struct iaddr addr
Definition: inet.h:54
struct iaddr lo_addr
Definition: inet.h:71
struct iaddr mask
Definition: inet.h:55
char * piaddrcidr(const struct iaddr *addr, unsigned int bits)
Definition: inet.c:637
isc_result_t range2cidr(struct iaddrcidrnetlist **result, const struct iaddr *lo, const struct iaddr *hi)
Definition: inet.c:360
int addr_and(struct iaddr *result, const struct iaddr *a1, const struct iaddr *a2)
Definition: inet.c:267