1/* dnsmasq is Copyright (c) 2000 - 2003 Simon Kelley 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; version 2 dated June, 1991. 6 7 This program is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 GNU General Public License for more details. 11*/ 12 13/* Author's email: simon@thekelleys.org.uk */ 14 15#include "dnsmasq.h" 16 17static struct irec *add_iface(struct daemon *daemon, struct irec *list, char *name, union mysockaddr *addr) 18{ 19 struct irec *iface; 20 struct iname *tmp; 21 22 /* check blacklist */ 23 if (daemon->if_except) 24 for (tmp = daemon->if_except; tmp; tmp = tmp->next) 25 if (tmp->name && strcmp(tmp->name, name) == 0) 26 { 27 /* record address of named interfaces, for TCP access control */ 28 tmp->addr = *addr; 29 return list; 30 } 31 32 /* we may need to check the whitelist */ 33 if (daemon->if_names || daemon->if_addrs) 34 { 35 int found = 0; 36 37 for (tmp = daemon->if_names; tmp; tmp = tmp->next) 38 if (tmp->name && (strcmp(tmp->name, name) == 0)) 39 { 40 tmp->addr = *addr; 41 found = tmp->used = 1; 42 } 43 44 for (tmp = daemon->if_addrs; tmp; tmp = tmp->next) 45 if (sockaddr_isequal(&tmp->addr, addr)) 46 found = tmp->used = 1; 47 48 if (!found) 49 return list; 50 } 51 52 /* check whether the interface IP has been added already 53 it is possible to have multiple interfaces with the same address */ 54 for (iface = list; iface; iface = iface->next) 55 if (sockaddr_isequal(&iface->addr, addr)) 56 break; 57 if (iface) 58 return list; 59 60 /* If OK, add it to the head of the list */ 61 iface = safe_malloc(sizeof(struct irec)); 62 iface->addr = *addr; 63 iface->next = list; 64 return iface; 65} 66 67 68struct irec *enumerate_interfaces(struct daemon *daemon) 69{ 70 struct irec *iface = NULL; 71 char *buf, *ptr; 72 struct ifreq *ifr = NULL; 73 struct ifconf ifc; 74 int lastlen = 0; 75 int len = 20 * sizeof(struct ifreq); 76 int fd = socket(PF_INET, SOCK_DGRAM, 0); 77 78 if (fd == -1) 79 die ("cannot create socket to enumerate interfaces: %s", NULL); 80 81 while (1) 82 { 83 buf = safe_malloc(len); 84 85 ifc.ifc_len = len; 86 ifc.ifc_buf = buf; 87 if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) 88 { 89 if (errno != EINVAL || lastlen != 0) 90 die ("ioctl error while enumerating interfaces: %s", NULL); 91 } 92 else 93 { 94 if (ifc.ifc_len == lastlen) 95 break; /* got a big enough buffer now */ 96 lastlen = ifc.ifc_len; 97 } 98 len += 10*sizeof(struct ifreq); 99 free(buf); 100 } 101 102 for (ptr = buf; ptr < buf + len; ) 103 { 104 union mysockaddr addr; 105#ifdef HAVE_SOCKADDR_SA_LEN 106 /* subsequent entries may not be aligned, so copy into 107 an aligned buffer to avoid nasty complaints about 108 unaligned accesses. */ 109 int ifr_len = ((struct ifreq *)ptr)->ifr_addr.sa_len + IF_NAMESIZE; 110 if (!(ifr = realloc(ifr, ifr_len))) 111 die("cannot allocate buffer", NULL); 112 113 memcpy(ifr, ptr, ifr_len); 114 ptr += ifr_len; 115#else 116 ifr = (struct ifreq *)ptr; 117 ptr += sizeof(struct ifreq); 118#endif 119 120 /* copy address since getting flags overwrites */ 121 if (ifr->ifr_addr.sa_family == AF_INET) 122 { 123 addr.in = *((struct sockaddr_in *) &ifr->ifr_addr); 124 addr.in.sin_port = htons(daemon->port); 125 } 126#ifdef HAVE_IPV6 127 else if (ifr->ifr_addr.sa_family == AF_INET6) 128 { 129#ifdef HAVE_BROKEN_SOCKADDR_IN6 130 addr.in6 = *((struct my_sockaddr_in6 *) &ifr->ifr_addr); 131#else 132 addr.in6 = *((struct sockaddr_in6 *) &ifr->ifr_addr); 133#endif 134 addr.in6.sin6_port = htons(daemon->port); 135 addr.in6.sin6_flowinfo = htonl(0); 136 } 137#endif 138 else 139 continue; /* unknown address family */ 140 141 if (ioctl(fd, SIOCGIFFLAGS, ifr) < 0) 142 die("ioctl error getting interface flags: %m", NULL); 143 144 /* If we are restricting the set of interfaces to use, make 145 sure that loopback interfaces are in that set. */ 146 if (daemon->if_names && (ifr->ifr_flags & IFF_LOOPBACK)) 147 { 148 struct iname *lo; 149 for (lo = daemon->if_names; lo; lo = lo->next) 150 if (lo->name && strcmp(lo->name, ifr->ifr_name) == 0) 151 { 152 lo->isloop = 1; 153 break; 154 } 155 if (!lo) 156 { 157 lo = safe_malloc(sizeof(struct iname)); 158 lo->name = safe_string_alloc(ifr->ifr_name); 159 lo->isloop = lo->used = 1; 160 lo->next = daemon->if_names; 161 daemon->if_names = lo; 162 } 163 } 164 165 iface = add_iface(daemon, iface, ifr->ifr_name, &addr); 166 167#if defined(HAVE_LINUX_IPV6_PROC) && defined(HAVE_IPV6) 168 /* IPv6 addresses don't seem to work with SIOCGIFCONF. Barf */ 169 /* This code snarfed from net-tools 1.60 and certainly linux specific, though 170 it shouldn't break on other Unices, and their SIOGIFCONF might work. */ 171 { 172 FILE *f = fopen(IP6INTERFACES, "r"); 173 int found = 0; 174 union mysockaddr addr6; 175 176 if (f) 177 { 178 unsigned int plen, scope, flags, if_idx; 179 char devname[20], addrstring[32]; 180 181 while (fscanf(f, "%32s %02x %02x %02x %02x %20s\n", 182 addrstring, &if_idx, &plen, &scope, &flags, devname) != EOF) 183 { 184 if (strcmp(devname, ifr->ifr_name) == 0) 185 { 186 int i; 187 unsigned char *addr6p = (unsigned char *) &addr6.in6.sin6_addr; 188 memset(&addr6, 0, sizeof(addr6)); 189 addr6.sa.sa_family = AF_INET6; 190 for (i=0; i<16; i++) 191 { 192 unsigned int byte; 193 sscanf(addrstring+i+i, "%02x", &byte); 194 addr6p[i] = byte; 195 } 196 addr6.in6.sin6_port = htons(daemon->port); 197 addr6.in6.sin6_flowinfo = htonl(0); 198 addr6.in6.sin6_scope_id = htonl(scope); 199 200 found = 1; 201 break; 202 } 203 } 204 205 fclose(f); 206 } 207 208 if (found) 209 iface = add_iface(daemon, iface, ifr->ifr_name, &addr6); 210 } 211#endif /* LINUX */ 212 } 213 214 if (buf) 215 free(buf); 216#ifdef HAVE_SOCKADDR_SA_LEN 217 if (ifr) 218 free(ifr); 219#endif 220 close(fd); 221 222 return iface; 223} 224 225#ifdef HAVE_IPV6 226static int create_ipv6_listener(struct listener **link, int port) 227{ 228 union mysockaddr addr; 229 int tcpfd, fd, flags, save; 230 struct listener *l; 231 int opt = 1; 232 233 addr.in6.sin6_family = AF_INET6; 234 addr.in6.sin6_addr = in6addr_any; 235 addr.in6.sin6_port = htons(port); 236 addr.in6.sin6_flowinfo = htonl(0); 237#ifdef HAVE_SOCKADDR_SA_LEN 238 addr.in6.sin6_len = sizeof(struct sockaddr_in6); 239#endif 240 241 /* No error of the kernel doesn't support IPv6 */ 242 if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) == -1) 243 return (errno == EPROTONOSUPPORT || 244 errno == EAFNOSUPPORT || 245 errno == EINVAL); 246 247 if ((tcpfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) 248 { 249 save = errno; 250 close(fd); 251 errno = save; 252 return 0; 253 } 254 255 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || 256 setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || 257 setsockopt(fd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 || 258 setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 || 259 (flags = fcntl(tcpfd, F_GETFL, 0)) == -1 || 260 fcntl(tcpfd, F_SETFL, flags | O_NONBLOCK) == -1 || 261#ifdef IPV6_RECVPKTINFO 262 setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1 || 263#else 264 setsockopt(fd, IPV6_LEVEL, IPV6_PKTINFO, &opt, sizeof(opt)) == -1 || 265#endif 266 bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 || 267 listen(tcpfd, 5) == -1 || 268 bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1) 269 { 270 save = errno; 271 close(fd); 272 close(tcpfd); 273 errno = save; 274 return 0; 275 } 276 277 l = safe_malloc(sizeof(struct listener)); 278 l->fd = fd; 279 l->tcpfd = tcpfd; 280 l->family = AF_INET6; 281 l->next = NULL; 282 *link = l; 283 284 return 1; 285} 286#endif 287 288struct listener *create_wildcard_listeners(int port) 289{ 290#if !(defined(IP_PKTINFO) || (defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR))) 291 return NULL; 292#else 293 union mysockaddr addr; 294 int opt = 1; 295 struct listener *l, *l6 = NULL; 296 int flags; 297 int tcpfd, fd; 298 299 addr.in.sin_family = AF_INET; 300 addr.in.sin_addr.s_addr = INADDR_ANY; 301 addr.in.sin_port = htons(port); 302#ifdef HAVE_SOCKADDR_SA_LEN 303 addr.in.sin_len = sizeof(struct sockaddr_in); 304#endif 305 306 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 307 return NULL; 308 309 if ((tcpfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 310 { 311 close (fd); 312 return NULL; 313 } 314 315 if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || 316 bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 || 317 listen(tcpfd, 5) == -1 || 318 (flags = fcntl(tcpfd, F_GETFL, 0)) == -1 || 319 fcntl(tcpfd, F_SETFL, flags | O_NONBLOCK) == -1 || 320#ifdef HAVE_IPV6 321 !create_ipv6_listener(&l6, port) || 322#endif 323 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || 324#if defined(IP_PKTINFO) 325 setsockopt(fd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1 || 326#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF) 327 setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 || 328 setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1 || 329#endif 330 bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1) 331 { 332 close(fd); 333 close(tcpfd); 334 return NULL; 335 } 336 337 l = safe_malloc(sizeof(struct listener)); 338 l->family = AF_INET; 339 l->fd = fd; 340 l->tcpfd = tcpfd; 341 l->next = l6; 342 343 return l; 344 345#endif 346} 347 348struct listener *create_bound_listeners(struct irec *interfaces, int port) 349{ 350 351 struct listener *listeners = NULL; 352 struct irec *iface; 353 int flags = port, opt = 1; 354 355 /* Create bound listeners only for IPv4, IPv6 always binds the wildcard */ 356 357#ifdef HAVE_IPV6 358 if (!create_ipv6_listener(&listeners, port)) 359 die("failed to to create listening socket: %s", NULL); 360#endif 361 362 for (iface = interfaces ;iface; iface = iface->next) 363 if (iface->addr.sa.sa_family == AF_INET) 364 { 365 struct listener *new = safe_malloc(sizeof(struct listener)); 366 new->family = iface->addr.sa.sa_family; 367 new->next = listeners; 368 listeners = new; 369 if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 || 370 (new->fd = socket(iface->addr.sa.sa_family, SOCK_DGRAM, 0)) == -1 || 371 setsockopt(new->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || 372 setsockopt(new->tcpfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || 373 /* See Stevens 16.6 */ 374 (flags = fcntl(new->tcpfd, F_GETFL, 0)) == -1 || 375 fcntl(new->tcpfd, F_SETFL, flags | O_NONBLOCK) == -1 || 376 bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1 || 377 bind(new->fd, &iface->addr.sa, sa_len(&iface->addr)) == -1 || 378 listen(new->tcpfd, 5) == -1) 379 die("failed to to create listening socket: %s", NULL); 380 } 381 382 return listeners; 383} 384 385struct serverfd *allocate_sfd(union mysockaddr *addr, struct serverfd **sfds) 386{ 387 struct serverfd *sfd; 388 389 /* may have a suitable one already */ 390 for (sfd = *sfds; sfd; sfd = sfd->next ) 391 if (sockaddr_isequal(&sfd->source_addr, addr)) 392 return sfd; 393 394 /* need to make a new one. */ 395 errno = ENOMEM; /* in case malloc fails. */ 396 if (!(sfd = malloc(sizeof(struct serverfd)))) 397 return NULL; 398 399 if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1) 400 { 401 free(sfd); 402 return NULL; 403 } 404 405 if (bind(sfd->fd, (struct sockaddr *)addr, sa_len(addr)) == -1) 406 { 407 int errsave = errno; /* save error from bind. */ 408 close(sfd->fd); 409 free(sfd); 410 errno = errsave; 411 return NULL; 412 } 413 414 sfd->source_addr = *addr; 415 sfd->next = *sfds; 416 *sfds = sfd; 417 418 return sfd; 419} 420 421void check_servers(struct daemon *daemon, struct irec *interfaces) 422{ 423 char addrbuff[ADDRSTRLEN]; 424 struct irec *iface; 425 struct server *new, *tmp, *ret = NULL; 426 int port = 0; 427 428 /* forward table rules reference servers, so have to blow them away */ 429 forward_init(0); 430 431 daemon->last_server = NULL; 432 433 for (new = daemon->servers; new; new = tmp) 434 { 435 tmp = new->next; 436 437 if (!(new->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR))) 438 { 439#ifdef HAVE_IPV6 440 if (new->addr.sa.sa_family == AF_INET) 441 { 442 inet_ntop(AF_INET, &new->addr.in.sin_addr, addrbuff, ADDRSTRLEN); 443 port = ntohs(new->addr.in.sin_port); 444 } 445 else if (new->addr.sa.sa_family == AF_INET6) 446 { 447 inet_ntop(AF_INET6, &new->addr.in6.sin6_addr, addrbuff, ADDRSTRLEN); 448 port = ntohs(new->addr.in6.sin6_port); 449 } 450#else 451 strcpy(addrbuff, inet_ntoa(new->addr.in.sin_addr)); 452 port = ntohs(new->addr.in.sin_port); 453#endif 454 for (iface = interfaces; iface; iface = iface->next) 455 if (sockaddr_isequal(&new->addr, &iface->addr)) 456 break; 457 if (iface) 458 { 459#ifdef USE_SYSLOG /* foxconn wklin added, 08/13/2007 */ 460 syslog(LOG_WARNING, "ignoring nameserver %s - local interface", addrbuff); 461#endif 462 free(new); 463 continue; 464 } 465 466 /* Do we need a socket set? */ 467 if (!new->sfd && !(new->sfd = allocate_sfd(&new->source_addr, &daemon->sfds))) 468 { 469#ifdef USE_SYSLOG /* foxconn wklin added, 08/13/2007 */ 470 syslog(LOG_WARNING, 471 "ignoring nameserver %s - cannot make/bind socket: %m", addrbuff); 472#endif 473 free(new); 474 continue; 475 } 476 } 477 478 /* reverse order - gets it right. */ 479 new->next = ret; 480 ret = new; 481 482 if (new->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS)) 483 { 484 char *s1, *s2; 485 if (new->flags & SERV_HAS_DOMAIN) 486 s1 = "domain", s2 = new->domain; 487 else 488 s1 = "unqualified", s2 = "domains"; 489 490#ifdef USE_SYSLOG /* foxconn wklin added, 08/13/2007 */ 491 if (new->flags & SERV_NO_ADDR) 492 syslog(LOG_INFO, "using local addresses only for %s %s", s1, s2); 493 else if (!(new->flags & SERV_LITERAL_ADDRESS)) 494 syslog(LOG_INFO, "using nameserver %s#%d for %s %s", addrbuff, port, s1, s2); 495#endif 496 } 497#ifdef USE_SYSLOG /* foxconn wklin added, 08/13/2007 */ 498 else 499 syslog(LOG_INFO, "using nameserver %s#%d", addrbuff, port); 500#endif 501 } 502 503 daemon->servers = ret; 504} 505 506void reload_servers(char *fname, struct daemon *daemon) 507{ 508 FILE *f; 509 char *line; 510 struct server *old_servers = NULL; 511 struct server *new_servers = NULL; 512 struct server *serv = daemon->servers; 513 514 /* move old servers to free list - we can reuse the memory 515 and not risk malloc if there are the same or fewer new servers. 516 Servers which were specced on the command line go to the new list. */ 517 while (serv) 518 { 519 struct server *tmp = serv->next; 520 if (serv->flags & SERV_FROM_RESOLV) 521 { 522 serv->next = old_servers; 523 old_servers = serv; 524 } 525 else 526 { 527 serv->next = new_servers; 528 new_servers = serv; 529 } 530 serv = tmp; 531 } 532 533 /* buff happens to be NAXDNAME long... */ 534 f = fopen(fname, "r"); 535 if (!f) 536 { 537#ifdef USE_SYSLOG /* foxconn wklin added, 08/13/2007 */ 538 syslog(LOG_ERR, "failed to read %s: %m", fname); 539#endif 540 } 541 else 542 { 543#ifdef USE_SYSLOG /* foxconn wklin added, 08/13/2007 */ 544 syslog(LOG_INFO, "reading %s", fname); 545#endif 546 while ((line = fgets(daemon->namebuff, MAXDNAME, f))) 547 { 548 union mysockaddr addr, source_addr; 549 char *token = strtok(line, " \t\n\r"); 550 struct server *serv; 551 552 if (!token || strcmp(token, "nameserver") != 0) 553 continue; 554 if (!(token = strtok(NULL, " \t\n\r"))) 555 continue; 556 557#ifdef HAVE_IPV6 558 if (inet_pton(AF_INET, token, &addr.in.sin_addr)) 559#else 560 if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1) 561#endif 562 { 563#ifdef HAVE_SOCKADDR_SA_LEN 564 source_addr.in.sin_len = addr.in.sin_len = sizeof(struct sockaddr_in); 565#endif 566 source_addr.in.sin_family = addr.in.sin_family = AF_INET; 567 addr.in.sin_port = htons(NAMESERVER_PORT); 568 source_addr.in.sin_addr.s_addr = INADDR_ANY; 569 source_addr.in.sin_port = htons(daemon->query_port); 570 } 571#ifdef HAVE_IPV6 572 else if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr)) 573 { 574#ifdef HAVE_SOCKADDR_SA_LEN 575 source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(struct sockaddr_in6); 576#endif 577 source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6; 578 addr.in6.sin6_port = htons(NAMESERVER_PORT); 579 source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = htonl(0); 580 source_addr.in6.sin6_addr = in6addr_any; 581 source_addr.in6.sin6_port = htons(daemon->query_port); 582 } 583#endif /* IPV6 */ 584 else 585 continue; 586 587 if (old_servers) 588 { 589 serv = old_servers; 590 old_servers = old_servers->next; 591 } 592 else if (!(serv = malloc(sizeof (struct server)))) 593 continue; 594 595 /* this list is reverse ordered: 596 it gets reversed again in check_servers */ 597 serv->next = new_servers; 598 new_servers = serv; 599 serv->addr = addr; 600 serv->source_addr = source_addr; 601 serv->domain = NULL; 602 serv->sfd = NULL; 603 serv->flags = SERV_FROM_RESOLV; 604 } 605 606 fclose(f); 607 } 608 609 /* Free any memory not used. */ 610 while(old_servers) 611 { 612 struct server *tmp = old_servers->next; 613 free(old_servers); 614 old_servers = tmp; 615 } 616 617 daemon->servers = new_servers; 618} 619 620 621 622 623 624 625 626