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