/* dnsmasq is Copyright (c) 2000-2017 Simon Kelley

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 dated June, 1991, or
   (at your option) version 3 dated 29 June, 2007.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
     
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "dnsmasq.h"


static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c);
#ifdef HAVE_IPV6
static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c);
#endif


int is_name_synthetic(int flags, char *name, struct all_addr *addr)
{
  char *p;
  struct cond_domain *c = NULL;
  int prot = AF_INET;

#ifdef HAVE_IPV6
  if (flags & F_IPV6)
    prot = AF_INET6;
#endif

  for (c = daemon->synth_domains; c; c = c->next)
    {
      int found = 0;
      char *tail, *pref;
      
      for (tail = name, pref = c->prefix; *tail != 0 && pref && *pref != 0; tail++, pref++)
	{
	  unsigned int c1 = (unsigned char) *pref;
	  unsigned int c2 = (unsigned char) *tail;
	  
	  if (c1 >= 'A' && c1 <= 'Z')
	    c1 += 'a' - 'A';
	  if (c2 >= 'A' && c2 <= 'Z')
	    c2 += 'a' - 'A';
	  
	  if (c1 != c2)
	    break;
	}
      
      if (pref && *pref != 0)
	continue; /* prefix match fail */
      
      /* NB, must not alter name if we return zero */
      for (p = tail; *p; p++)
	{
	  char c = *p;
	  
	  if ((c >='0' && c <= '9') || c == '-')
	    continue;
	  
#ifdef HAVE_IPV6
	  if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f'))) 
	    continue;
#endif
	  
	  break;
	}
      
      if (*p != '.')
	continue;
      
      *p = 0;	
      
 #ifdef HAVE_IPV6
      if (prot == AF_INET6 && strstr(tail, "--ffff-") == tail)
	{
	  /* special hack for v4-mapped. */
	  memcpy(tail, "::ffff:", 7);
	  for (p = tail + 7; *p; p++)
	    if (*p == '-')
	      *p = '.';
	}
      else
#endif
	{
	  /* swap . or : for - */
	  for (p = tail; *p; p++)
	    if (*p == '-')
	      {
		if (prot == AF_INET)
		  *p = '.';
#ifdef HAVE_IPV6
		else
		  *p = ':';
#endif
	      }
	}

      if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
	{
	  if (prot == AF_INET)
	    {
	      if (!c->is6 &&
		  ntohl(addr->addr.addr4.s_addr) >= ntohl(c->start.s_addr) &&
		  ntohl(addr->addr.addr4.s_addr) <= ntohl(c->end.s_addr))
		found = 1;
	    }
#ifdef HAVE_IPV6
	  else
	    {
	      u64 addrpart = addr6part(&addr->addr.addr6);
	      
	      if (c->is6 &&
		  is_same_net6(&addr->addr.addr6, &c->start6, 64) &&
		  addrpart >= addr6part(&c->start6) &&
		  addrpart <= addr6part(&c->end6))
		found = 1;
	    }
#endif
	}
      
      /* restore name */
      for (p = tail; *p; p++)
	if (*p == '.' || *p == ':')
	  *p = '-';
      
      *p = '.';

      if (found)
	return 1;
    }
  
  return 0;
}


int is_rev_synth(int flag, struct all_addr *addr, char *name)
{
   struct cond_domain *c;

   if (flag & F_IPV4 && (c = search_domain(addr->addr.addr4, daemon->synth_domains))) 
     {
       char *p;
       
       *name = 0;
       if (c->prefix)
	 strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
       
       inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN);
       for (p = name; *p; p++)
	 if (*p == '.')
	   *p = '-';

       strncat(name, ".", MAXDNAME);
       strncat(name, c->domain, MAXDNAME);

       return 1;
     }

#ifdef HAVE_IPV6
   if (flag & F_IPV6 && (c = search_domain6(&addr->addr.addr6, daemon->synth_domains))) 
     {
       char *p;
       
       *name = 0;
       if (c->prefix)
	 strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
       
       inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN);

       /* IPv6 presentation address can start with ":", but valid domain names
	  cannot start with "-" so prepend a zero in that case. */
       if (!c->prefix && *name == ':')
	 {
	   *name = '0';
	   inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN);
	 }

       /* V4-mapped have periods.... */
       for (p = name; *p; p++)
	 if (*p == ':' || *p == '.')
	   *p = '-';

       strncat(name, ".", MAXDNAME);
       strncat(name, c->domain, MAXDNAME);
       
       return 1;
     }
#endif
   
   return 0;
}


static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c)
{
  for (; c; c = c->next)
    if (!c->is6 &&
	ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
        ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
      return c;

  return NULL;
}

char *get_domain(struct in_addr addr)
{
  struct cond_domain *c;

  if ((c = search_domain(addr, daemon->cond_domain)))
    return c->domain;

  return daemon->domain_suffix;
} 

#ifdef HAVE_IPV6
static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
{
  u64 addrpart = addr6part(addr);
  
  for (; c; c = c->next)
    if (c->is6 &&
	is_same_net6(addr, &c->start6, 64) &&
	addrpart >= addr6part(&c->start6) &&
        addrpart <= addr6part(&c->end6))
      return c;
  
  return NULL;
}

char *get_domain6(struct in6_addr *addr)
{
  struct cond_domain *c;

  if (addr && (c = search_domain6(addr, daemon->cond_domain)))
    return c->domain;

  return daemon->domain_suffix;
} 
#endif
