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