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