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
rand_init(void)32 void rand_init(void)
33 {
34 return;
35 }
36
rand16(void)37 unsigned short rand16(void)
38 {
39 return (unsigned short) (arc4random() >> 15);
40 }
41
42 #else
43
44 /* SURF random number generator */
45
46 typedef unsigned int uint32;
47
48 static uint32 seed[32];
49 static uint32 in[12];
50 static uint32 out[8];
51
rand_init()52 void 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
surf(void)67 static 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
rand16(void)86 unsigned 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
check_name(char * in)101 static 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. */
legal_hostname(char * name)144 int 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
canonicalise(char * in,int * nomem)170 char *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
do_rfc1035_name(unsigned char * p,char * sval)207 unsigned 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 */
safe_malloc(size_t size)224 void *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
safe_pipe(int * fd,int read_noblock)234 void 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
whine_malloc(size_t size)242 void *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
sockaddr_isequal(union mysockaddr * s1,union mysockaddr * s2)252 int 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
sa_len(union mysockaddr * addr)270 int 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 */
hostname_isequal(char * a,char * b)285 int 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
dnsmasq_time(void)305 time_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
is_same_net(struct in_addr a,struct in_addr b,struct in_addr mask)320 int 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 */
prettyprint_addr(union mysockaddr * addr,char * buf)326 int 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
prettyprint_time(char * buf,unsigned int t)349 void 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). */
parse_hex(char * in,unsigned char * out,int maxlen,unsigned int * wildcard_mask,int * mac_type)369 int 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 */
memcmp_masked(unsigned char * a,unsigned char * b,int len,unsigned int mask)413 int 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 */
expand_buf(struct iovec * iov,size_t size)428 int 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
print_mac(char * buff,unsigned char * mac,int len)453 char *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
bump_maxfd(int fd,int * max)467 void bump_maxfd(int fd, int *max)
468 {
469 if (fd > *max)
470 *max = fd;
471 }
472
retry_send(void)473 int 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
read_write(int fd,unsigned char * packet,int size,int rw)490 int 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