xref: /aosp_15_r20/external/dnsmasq/src/util.c (revision c2c26c8b25cb2c9c4fe49a734c2305a522f5635e)
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