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