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