1/* dnsmasq is Copyright (c) 2000-2009 Simon Kelley
2
3   This program is free software; you can redistribute it and/or modify
4   it under the terms of the GNU General Public License as published by
5   the Free Software Foundation; version 2 dated June, 1991, or
6   (at your option) version 3 dated 29 June, 2007.
7
8   This program is distributed in the hope that it will be useful,
9   but WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   GNU General Public License for more details.
12
13   You should have received a copy of the GNU General Public License
14   along with this program.  If not, see <http://www.gnu.org/licenses/>.
15*/
16
17/* The SURF random number generator was taken from djbdns-1.05, by
18   Daniel J Bernstein, which is public domain. */
19
20
21#include "dnsmasq.h"
22
23#ifdef HAVE_BROKEN_RTC
24#include <sys/times.h>
25#endif
26
27#ifdef LOCALEDIR
28#include <idna.h>
29#endif
30
31#ifdef HAVE_ARC4RANDOM
32void rand_init(void)
33{
34  return;
35}
36
37unsigned short rand16(void)
38{
39   return (unsigned short) (arc4random() >> 15);
40}
41
42#else
43
44/* SURF random number generator */
45
46typedef unsigned int uint32;
47
48static uint32 seed[32];
49static uint32 in[12];
50static uint32 out[8];
51
52void rand_init()
53{
54  int fd = open(RANDFILE, O_RDONLY);
55
56  if (fd == -1 ||
57      !read_write(fd, (unsigned char *)&seed, sizeof(seed), 1) ||
58      !read_write(fd, (unsigned char *)&in, sizeof(in), 1))
59    die(_("failed to seed the random number generator: %s"), NULL, EC_MISC);
60
61  close(fd);
62}
63
64#define ROTATE(x,b) (((x) << (b)) | ((x) >> (32 - (b))))
65#define MUSH(i,b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x,b));
66
67static void surf(void)
68{
69  uint32 t[12]; uint32 x; uint32 sum = 0;
70  int r; int i; int loop;
71
72  for (i = 0;i < 12;++i) t[i] = in[i] ^ seed[12 + i];
73  for (i = 0;i < 8;++i) out[i] = seed[24 + i];
74  x = t[11];
75  for (loop = 0;loop < 2;++loop) {
76    for (r = 0;r < 16;++r) {
77      sum += 0x9e3779b9;
78      MUSH(0,5) MUSH(1,7) MUSH(2,9) MUSH(3,13)
79      MUSH(4,5) MUSH(5,7) MUSH(6,9) MUSH(7,13)
80      MUSH(8,5) MUSH(9,7) MUSH(10,9) MUSH(11,13)
81    }
82    for (i = 0;i < 8;++i) out[i] ^= t[i + 4];
83  }
84}
85
86unsigned short rand16(void)
87{
88  static int outleft = 0;
89
90  if (!outleft) {
91    if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
92    surf();
93    outleft = 8;
94  }
95
96  return (unsigned short) out[--outleft];
97}
98
99#endif
100
101static int check_name(char *in)
102{
103  /* remove trailing .
104     also fail empty string and label > 63 chars */
105  size_t dotgap = 0, l = strlen(in);
106  char c;
107  int nowhite = 0;
108
109  if (l == 0 || l > MAXDNAME) return 0;
110
111  if (in[l-1] == '.')
112    {
113      if (l == 1) return 0;
114      in[l-1] = 0;
115    }
116
117  for (; (c = *in); in++)
118    {
119      if (c == '.')
120	dotgap = 0;
121      else if (++dotgap > MAXLABEL)
122	return 0;
123      else if (isascii(c) && iscntrl(c))
124	/* iscntrl only gives expected results for ascii */
125	return 0;
126#ifndef LOCALEDIR
127      else if (!isascii(c))
128	return 0;
129#endif
130      else if (c != ' ')
131	nowhite = 1;
132    }
133
134  if (!nowhite)
135    return 0;
136
137  return 1;
138}
139
140/* Hostnames have a more limited valid charset than domain names
141   so check for legal char a-z A-Z 0-9 - _
142   Note that this may receive a FQDN, so only check the first label
143   for the tighter criteria. */
144int legal_hostname(char *name)
145{
146  char c;
147
148  if (!check_name(name))
149    return 0;
150
151  for (; (c = *name); name++)
152    /* check for legal char a-z A-Z 0-9 - _ . */
153    {
154      if ((c >= 'A' && c <= 'Z') ||
155	  (c >= 'a' && c <= 'z') ||
156	  (c >= '0' && c <= '9') ||
157	  c == '-' || c == '_')
158	continue;
159
160      /* end of hostname part */
161      if (c == '.')
162	return 1;
163
164      return 0;
165    }
166
167  return 1;
168}
169
170char *canonicalise(char *in, int *nomem)
171{
172  char *ret = NULL;
173#ifdef LOCALEDIR
174  int rc;
175#endif
176
177  if (nomem)
178    *nomem = 0;
179
180  if (!check_name(in))
181    return NULL;
182
183#ifdef LOCALEDIR
184  if ((rc = idna_to_ascii_lz(in, &ret, 0)) != IDNA_SUCCESS)
185    {
186      if (ret)
187	free(ret);
188
189      if (nomem && (rc == IDNA_MALLOC_ERROR || rc == IDNA_DLOPEN_ERROR))
190	{
191	  my_syslog(LOG_ERR, _("failed to allocate memory"));
192	  *nomem = 1;
193	}
194
195      return NULL;
196    }
197#else
198  if ((ret = whine_malloc(strlen(in)+1)))
199    strcpy(ret, in);
200  else if (nomem)
201    *nomem = 1;
202#endif
203
204  return ret;
205}
206
207unsigned char *do_rfc1035_name(unsigned char *p, char *sval)
208{
209  int j;
210
211  while (sval && *sval)
212    {
213      unsigned char *cp = p++;
214      for (j = 0; *sval && (*sval != '.'); sval++, j++)
215	*p++ = *sval;
216      *cp  = j;
217      if (*sval)
218	sval++;
219    }
220  return p;
221}
222
223/* for use during startup */
224void *safe_malloc(size_t size)
225{
226  void *ret = malloc(size);
227
228  if (!ret)
229    die(_("could not get memory"), NULL, EC_NOMEM);
230
231  return ret;
232}
233
234void safe_pipe(int *fd, int read_noblock)
235{
236  if (pipe(fd) == -1 ||
237      !fix_fd(fd[1]) ||
238      (read_noblock && !fix_fd(fd[0])))
239    die(_("cannot create pipe: %s"), NULL, EC_MISC);
240}
241
242void *whine_malloc(size_t size)
243{
244  void *ret = malloc(size);
245
246  if (!ret)
247    my_syslog(LOG_ERR, _("failed to allocate %d bytes"), (int) size);
248
249  return ret;
250}
251
252int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2)
253{
254  if (s1->sa.sa_family == s2->sa.sa_family)
255    {
256      if (s1->sa.sa_family == AF_INET &&
257	  s1->in.sin_port == s2->in.sin_port &&
258	  s1->in.sin_addr.s_addr == s2->in.sin_addr.s_addr)
259	return 1;
260#ifdef HAVE_IPV6
261      if (s1->sa.sa_family == AF_INET6 &&
262	  s1->in6.sin6_port == s2->in6.sin6_port &&
263	  IN6_ARE_ADDR_EQUAL(&s1->in6.sin6_addr, &s2->in6.sin6_addr))
264	return 1;
265#endif
266    }
267  return 0;
268}
269
270int sa_len(union mysockaddr *addr)
271{
272#ifdef HAVE_SOCKADDR_SA_LEN
273  return addr->sa.sa_len;
274#else
275#ifdef HAVE_IPV6
276  if (addr->sa.sa_family == AF_INET6)
277    return sizeof(addr->in6);
278  else
279#endif
280    return sizeof(addr->in);
281#endif
282}
283
284/* don't use strcasecmp and friends here - they may be messed up by LOCALE */
285int hostname_isequal(char *a, char *b)
286{
287  unsigned int c1, c2;
288
289  do {
290    c1 = (unsigned char) *a++;
291    c2 = (unsigned char) *b++;
292
293    if (c1 >= 'A' && c1 <= 'Z')
294      c1 += 'a' - 'A';
295    if (c2 >= 'A' && c2 <= 'Z')
296      c2 += 'a' - 'A';
297
298    if (c1 != c2)
299      return 0;
300  } while (c1);
301
302  return 1;
303}
304
305time_t dnsmasq_time(void)
306{
307#ifdef HAVE_BROKEN_RTC
308  struct tms dummy;
309  static long tps = 0;
310
311  if (tps == 0)
312    tps = sysconf(_SC_CLK_TCK);
313
314  return (time_t)(times(&dummy)/tps);
315#else
316  return time(NULL);
317#endif
318}
319
320int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask)
321{
322  return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
323}
324
325/* returns port number from address */
326int prettyprint_addr(union mysockaddr *addr, char *buf)
327{
328  int port = 0;
329
330#ifdef HAVE_IPV6
331  if (addr->sa.sa_family == AF_INET)
332    {
333      inet_ntop(AF_INET, &addr->in.sin_addr, buf, ADDRSTRLEN);
334      port = ntohs(addr->in.sin_port);
335    }
336  else if (addr->sa.sa_family == AF_INET6)
337    {
338      inet_ntop(AF_INET6, &addr->in6.sin6_addr, buf, ADDRSTRLEN);
339      port = ntohs(addr->in6.sin6_port);
340    }
341#else
342  strcpy(buf, inet_ntoa(addr->in.sin_addr));
343  port = ntohs(addr->in.sin_port);
344#endif
345
346  return port;
347}
348
349void prettyprint_time(char *buf, unsigned int t)
350{
351  if (t == 0xffffffff)
352    sprintf(buf, _("infinite"));
353  else
354    {
355      unsigned int x, p = 0;
356       if ((x = t/86400))
357	p += sprintf(&buf[p], "%dd", x);
358       if ((x = (t/3600)%24))
359	p += sprintf(&buf[p], "%dh", x);
360      if ((x = (t/60)%60))
361	p += sprintf(&buf[p], "%dm", x);
362      if ((x = t%60))
363	p += sprintf(&buf[p], "%ds", x);
364    }
365}
366
367
368/* in may equal out, when maxlen may be -1 (No max len). */
369int parse_hex(char *in, unsigned char *out, int maxlen,
370	      unsigned int *wildcard_mask, int *mac_type)
371{
372  int mask = 0, i = 0;
373  char *r;
374
375  if (mac_type)
376    *mac_type = 0;
377
378  while (maxlen == -1 || i < maxlen)
379    {
380      for (r = in; *r != 0 && *r != ':' && *r != '-'; r++);
381      if (*r == 0)
382	maxlen = i;
383
384      if (r != in )
385	{
386	  if (*r == '-' && i == 0 && mac_type)
387	   {
388	      *r = 0;
389	      *mac_type = strtol(in, NULL, 16);
390	      mac_type = NULL;
391	   }
392	  else
393	    {
394	      *r = 0;
395	      mask = mask << 1;
396	      if (strcmp(in, "*") == 0)
397		mask |= 1;
398	      else
399		out[i] = strtol(in, NULL, 16);
400	      i++;
401	    }
402	}
403      in = r+1;
404    }
405
406  if (wildcard_mask)
407    *wildcard_mask = mask;
408
409  return i;
410}
411
412/* return 0 for no match, or (no matched octets) + 1 */
413int memcmp_masked(unsigned char *a, unsigned char *b, int len, unsigned int mask)
414{
415  int i, count;
416  for (count = 1, i = len - 1; i >= 0; i--, mask = mask >> 1)
417    if (!(mask & 1))
418      {
419	if (a[i] == b[i])
420	  count++;
421	else
422	  return 0;
423      }
424  return count;
425}
426
427/* _note_ may copy buffer */
428int expand_buf(struct iovec *iov, size_t size)
429{
430  void *new;
431
432  if (size <= (size_t)iov->iov_len)
433    return 1;
434
435  if (!(new = whine_malloc(size)))
436    {
437      errno = ENOMEM;
438      return 0;
439    }
440
441  if (iov->iov_base)
442    {
443      memcpy(new, iov->iov_base, iov->iov_len);
444      free(iov->iov_base);
445    }
446
447  iov->iov_base = new;
448  iov->iov_len = size;
449
450  return 1;
451}
452
453char *print_mac(char *buff, unsigned char *mac, int len)
454{
455  char *p = buff;
456  int i;
457
458  if (len == 0)
459    sprintf(p, "<null>");
460  else
461    for (i = 0; i < len; i++)
462      p += sprintf(p, "%.2x%s", mac[i], (i == len - 1) ? "" : ":");
463
464  return buff;
465}
466
467void bump_maxfd(int fd, int *max)
468{
469  if (fd > *max)
470    *max = fd;
471}
472
473int retry_send(void)
474{
475   struct timespec waiter;
476   if (errno == EAGAIN)
477     {
478       waiter.tv_sec = 0;
479       waiter.tv_nsec = 10000;
480       nanosleep(&waiter, NULL);
481       return 1;
482     }
483
484   if (errno == EINTR)
485     return 1;
486
487   return 0;
488}
489
490int read_write(int fd, unsigned char *packet, int size, int rw)
491{
492  ssize_t n, done;
493
494  for (done = 0; done < size; done += n)
495    {
496    retry:
497      if (rw)
498        n = read(fd, &packet[done], (size_t)(size - done));
499      else
500        n = write(fd, &packet[done], (size_t)(size - done));
501
502      if (n == 0)
503        return 0;
504      else if (n == -1)
505        {
506          if (retry_send() || errno == ENOMEM || errno == ENOBUFS)
507            goto retry;
508          else
509            return 0;
510        }
511    }
512  return 1;
513}
514
515