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