Home | History | Annotate | Download | only in src
      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
     34 void rand_init(void)
     35 {
     36   return;
     37 }
     38 
     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 
     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 
     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 
     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 
    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. */
    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 
    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 
    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 */
    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 
    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 
    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 
    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 
    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 */
    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 
    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 
    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 
    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 */
    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 
    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). */
    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 */
    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 */
    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 
    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 
    496 void bump_maxfd(int fd, int *max)
    497 {
    498   if (fd > *max)
    499     *max = fd;
    500 }
    501 
    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 
    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