version 1.1.1.1, 2013/07/29 19:37:40
|
version 1.1.1.3, 2016/11/02 09:57:01
|
Line 1
|
Line 1
|
/* dnsmasq is Copyright (c) 2000-2013 Simon Kelley | /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley |
|
|
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
Line 28
|
Line 28
|
#include <idna.h> |
#include <idna.h> |
#endif |
#endif |
|
|
#ifdef HAVE_ARC4RANDOM |
|
void rand_init(void) |
|
{ |
|
return; |
|
} |
|
|
|
unsigned short rand16(void) |
|
{ |
|
return (unsigned short) (arc4random() >> 15); |
|
} |
|
|
|
#else |
|
|
|
/* SURF random number generator */ |
/* SURF random number generator */ |
|
|
static u32 seed[32]; |
static u32 seed[32]; |
static u32 in[12]; |
static u32 in[12]; |
static u32 out[8]; |
static u32 out[8]; |
|
static int outleft = 0; |
|
|
void rand_init() |
void rand_init() |
{ |
{ |
Line 83 static void surf(void)
|
Line 71 static void surf(void)
|
|
|
unsigned short rand16(void) |
unsigned short rand16(void) |
{ |
{ |
|
if (!outleft) |
|
{ |
|
if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3]; |
|
surf(); |
|
outleft = 8; |
|
} |
|
|
|
return (unsigned short) out[--outleft]; |
|
} |
|
|
|
u32 rand32(void) |
|
{ |
|
if (!outleft) |
|
{ |
|
if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3]; |
|
surf(); |
|
outleft = 8; |
|
} |
|
|
|
return out[--outleft]; |
|
} |
|
|
|
u64 rand64(void) |
|
{ |
static int outleft = 0; |
static int outleft = 0; |
|
|
if (!outleft) { | if (outleft < 2) |
if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3]; | { |
surf(); | if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3]; |
outleft = 8; | surf(); |
} | outleft = 8; |
| } |
| |
| outleft -= 2; |
|
|
return (unsigned short) out[--outleft]; | return (u64)out[outleft+1] + (((u64)out[outleft]) << 32); |
} |
} |
|
|
#endif |
|
|
|
static int check_name(char *in) |
static int check_name(char *in) |
{ |
{ |
/* remove trailing . |
/* remove trailing . |
Line 108 static int check_name(char *in)
|
Line 121 static int check_name(char *in)
|
|
|
if (in[l-1] == '.') |
if (in[l-1] == '.') |
{ |
{ |
if (l == 1) return 0; |
|
in[l-1] = 0; |
in[l-1] = 0; |
|
nowhite = 1; |
} |
} |
| |
for (; (c = *in); in++) |
for (; (c = *in); in++) |
{ |
{ |
if (c == '.') |
if (c == '.') |
Line 142 static int check_name(char *in)
|
Line 155 static int check_name(char *in)
|
int legal_hostname(char *name) |
int legal_hostname(char *name) |
{ |
{ |
char c; |
char c; |
|
int first; |
|
|
if (!check_name(name)) |
if (!check_name(name)) |
return 0; |
return 0; |
|
|
for (; (c = *name); name++) | for (first = 1; (c = *name); name++, first = 0) |
/* check for legal char a-z A-Z 0-9 - _ . */ |
/* check for legal char a-z A-Z 0-9 - _ . */ |
{ |
{ |
if ((c >= 'A' && c <= 'Z') || |
if ((c >= 'A' && c <= 'Z') || |
(c >= 'a' && c <= 'z') || |
(c >= 'a' && c <= 'z') || |
(c >= '0' && c <= '9') || | (c >= '0' && c <= '9')) |
c == '-' || c == '_') | |
continue; |
continue; |
|
|
|
if (!first && (c == '-' || c == '_')) |
|
continue; |
|
|
/* end of hostname part */ |
/* end of hostname part */ |
if (c == '.') |
if (c == '.') |
Line 210 unsigned char *do_rfc1035_name(unsigned char *p, char
|
Line 226 unsigned char *do_rfc1035_name(unsigned char *p, char
|
{ |
{ |
unsigned char *cp = p++; |
unsigned char *cp = p++; |
for (j = 0; *sval && (*sval != '.'); sval++, j++) |
for (j = 0; *sval && (*sval != '.'); sval++, j++) |
*p++ = *sval; | { |
| #ifdef HAVE_DNSSEC |
| if (option_bool(OPT_DNSSEC_VALID) && *sval == NAME_ESCAPE) |
| *p++ = (*(++sval))-1; |
| else |
| #endif |
| *p++ = *sval; |
| } |
*cp = j; |
*cp = j; |
if (*sval) |
if (*sval) |
sval++; |
sval++; |
Line 258 int sockaddr_isequal(union mysockaddr *s1, union mysoc
|
Line 281 int sockaddr_isequal(union mysockaddr *s1, union mysoc
|
#ifdef HAVE_IPV6 |
#ifdef HAVE_IPV6 |
if (s1->sa.sa_family == AF_INET6 && |
if (s1->sa.sa_family == AF_INET6 && |
s1->in6.sin6_port == s2->in6.sin6_port && |
s1->in6.sin6_port == s2->in6.sin6_port && |
|
s1->in6.sin6_scope_id == s2->in6.sin6_scope_id && |
IN6_ARE_ADDR_EQUAL(&s1->in6.sin6_addr, &s2->in6.sin6_addr)) |
IN6_ARE_ADDR_EQUAL(&s1->in6.sin6_addr, &s2->in6.sin6_addr)) |
return 1; |
return 1; |
#endif |
#endif |
Line 315 time_t dnsmasq_time(void)
|
Line 339 time_t dnsmasq_time(void)
|
#endif |
#endif |
} |
} |
|
|
|
int netmask_length(struct in_addr mask) |
|
{ |
|
int zero_count = 0; |
|
|
|
while (0x0 == (mask.s_addr & 0x1) && zero_count < 32) |
|
{ |
|
mask.s_addr >>= 1; |
|
zero_count++; |
|
} |
|
|
|
return 32 - zero_count; |
|
} |
|
|
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask) |
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask) |
{ |
{ |
return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr); |
return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr); |
Line 454 int parse_hex(char *in, unsigned char *out, int maxlen
|
Line 491 int parse_hex(char *in, unsigned char *out, int maxlen
|
int j, bytes = (1 + (r - in))/2; |
int j, bytes = (1 + (r - in))/2; |
for (j = 0; j < bytes; j++) |
for (j = 0; j < bytes; j++) |
{ |
{ |
char sav; | char sav = sav; |
if (j < bytes - 1) |
if (j < bytes - 1) |
{ |
{ |
sav = in[(j+1)*2]; |
sav = in[(j+1)*2]; |
Line 533 char *print_mac(char *buff, unsigned char *mac, int le
|
Line 570 char *print_mac(char *buff, unsigned char *mac, int le
|
return buff; |
return buff; |
} |
} |
|
|
void bump_maxfd(int fd, int *max) | /* rc is return from sendto and friends. |
| Return 1 if we should retry. |
| Set errno to zero if we succeeded. */ |
| int retry_send(ssize_t rc) |
{ |
{ |
if (fd > *max) | static int retries = 0; |
*max = fd; | struct timespec waiter; |
} | |
| if (rc != -1) |
| { |
| retries = 0; |
| errno = 0; |
| return 0; |
| } |
| |
| /* Linux kernels can return EAGAIN in perpetuity when calling |
| sendmsg() and the relevant interface has gone. Here we loop |
| retrying in EAGAIN for 1 second max, to avoid this hanging |
| dnsmasq. */ |
|
|
int retry_send(void) | if (errno == EAGAIN || errno == EWOULDBLOCK) |
{ | |
struct timespec waiter; | |
if (errno == EAGAIN || errno == EWOULDBLOCK) | |
{ |
{ |
waiter.tv_sec = 0; |
waiter.tv_sec = 0; |
waiter.tv_nsec = 10000; |
waiter.tv_nsec = 10000; |
nanosleep(&waiter, NULL); |
nanosleep(&waiter, NULL); |
return 1; | if (retries++ < 1000) |
| return 1; |
} |
} |
| |
if (errno == EINTR) | retries = 0; |
return 1; | |
| if (errno == EINTR) |
return 0; | return 1; |
| |
| return 0; |
} |
} |
|
|
int read_write(int fd, unsigned char *packet, int size, int rw) |
int read_write(int fd, unsigned char *packet, int size, int rw) |
Line 562 int read_write(int fd, unsigned char *packet, int size
|
Line 613 int read_write(int fd, unsigned char *packet, int size
|
|
|
for (done = 0; done < size; done += n) |
for (done = 0; done < size; done += n) |
{ |
{ |
retry: | do { |
if (rw) | if (rw) |
n = read(fd, &packet[done], (size_t)(size - done)); | n = read(fd, &packet[done], (size_t)(size - done)); |
else | else |
n = write(fd, &packet[done], (size_t)(size - done)); | n = write(fd, &packet[done], (size_t)(size - done)); |
| |
| if (n == 0) |
| return 0; |
| |
| } while (retry_send(n) || errno == ENOMEM || errno == ENOBUFS); |
|
|
if (n == 0) | if (errno != 0) |
return 0; | return 0; |
else if (n == -1) | |
{ | |
if (retry_send() || errno == ENOMEM || errno == ENOBUFS) | |
goto retry; | |
else | |
return 0; | |
} | |
} |
} |
|
|
return 1; |
return 1; |
} |
} |
|
|
Line 597 int wildcard_match(const char* wildcard, const char* m
|
Line 647 int wildcard_match(const char* wildcard, const char* m
|
} |
} |
|
|
return *wildcard == *match; |
return *wildcard == *match; |
|
} |
|
|
|
/* The same but comparing a maximum of NUM characters, like strncmp. */ |
|
int wildcard_matchn(const char* wildcard, const char* match, int num) |
|
{ |
|
while (*wildcard && *match && num) |
|
{ |
|
if (*wildcard == '*') |
|
return 1; |
|
|
|
if (*wildcard != *match) |
|
return 0; |
|
|
|
++wildcard; |
|
++match; |
|
--num; |
|
} |
|
|
|
return (!num) || (*wildcard == *match); |
} |
} |