File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / domain.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:56:46 2021 UTC (3 years, 4 months ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v2_84, HEAD
dnsmasq 2.84

    1: /* dnsmasq is Copyright (c) 2000-2021 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, or
    6:    (at your option) version 3 dated 29 June, 2007.
    7:  
    8:    This program is distributed in the hope that it will be useful,
    9:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   10:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11:    GNU General Public License for more details.
   12:      
   13:    You should have received a copy of the GNU General Public License
   14:    along with this program.  If not, see <http://www.gnu.org/licenses/>.
   15: */
   16: 
   17: #include "dnsmasq.h"
   18: 
   19: 
   20: static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c);
   21: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c);
   22: 
   23: 
   24: int is_name_synthetic(int flags, char *name, union all_addr *addr)
   25: {
   26:   char *p;
   27:   struct cond_domain *c = NULL;
   28:   int prot = (flags & F_IPV6) ? AF_INET6 : AF_INET;
   29: 
   30:   for (c = daemon->synth_domains; c; c = c->next)
   31:     {
   32:       int found = 0;
   33:       char *tail, *pref;
   34:       
   35:       for (tail = name, pref = c->prefix; *tail != 0 && pref && *pref != 0; tail++, pref++)
   36: 	{
   37: 	  unsigned int c1 = (unsigned char) *pref;
   38: 	  unsigned int c2 = (unsigned char) *tail;
   39: 	  
   40: 	  if (c1 >= 'A' && c1 <= 'Z')
   41: 	    c1 += 'a' - 'A';
   42: 	  if (c2 >= 'A' && c2 <= 'Z')
   43: 	    c2 += 'a' - 'A';
   44: 	  
   45: 	  if (c1 != c2)
   46: 	    break;
   47: 	}
   48:       
   49:       if (pref && *pref != 0)
   50: 	continue; /* prefix match fail */
   51: 
   52:       if (c->indexed)
   53: 	{
   54: 	  for (p = tail; *p; p++)
   55: 	    {
   56: 	      char c = *p;
   57: 	      
   58: 	      if (c < '0' || c > '9')
   59: 		break;
   60: 	    }
   61: 	  
   62: 	  if (*p != '.')
   63: 	    continue;
   64: 	  
   65: 	  *p = 0;
   66: 	  
   67: 	  if (hostname_isequal(c->domain, p+1))
   68: 	    {
   69: 	      if (prot == AF_INET)
   70: 		{
   71: 		  unsigned int index = atoi(tail);
   72: 
   73: 		   if (!c->is6 &&
   74: 		      index <= ntohl(c->end.s_addr) - ntohl(c->start.s_addr))
   75: 		    {
   76: 		      addr->addr4.s_addr = htonl(ntohl(c->start.s_addr) + index);
   77: 		      found = 1;
   78: 		    }
   79: 		} 
   80: 	      else
   81: 		{
   82: 		  u64 index = atoll(tail);
   83: 		  
   84: 		  if (c->is6 &&
   85: 		      index <= addr6part(&c->end6) - addr6part(&c->start6))
   86: 		    {
   87: 		      u64 start = addr6part(&c->start6);
   88: 		      addr->addr6 = c->start6;
   89: 		      setaddr6part(&addr->addr6, start + index);
   90: 		      found = 1;
   91: 		    }
   92: 		}
   93: 	    }
   94: 	}
   95:       else
   96: 	{
   97: 	  /* NB, must not alter name if we return zero */
   98: 	  for (p = tail; *p; p++)
   99: 	    {
  100: 	      char c = *p;
  101: 	      
  102: 	      if ((c >='0' && c <= '9') || c == '-')
  103: 		continue;
  104: 	      
  105: 	      if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f'))) 
  106: 		continue;
  107: 	      
  108: 	      break;
  109: 	    }
  110: 	  
  111: 	  if (*p != '.')
  112: 	    continue;
  113: 	  
  114: 	  *p = 0;	
  115: 	  
  116: 	  if (prot == AF_INET6 && strstr(tail, "--ffff-") == tail)
  117: 	    {
  118: 	      /* special hack for v4-mapped. */
  119: 	      memcpy(tail, "::ffff:", 7);
  120: 	      for (p = tail + 7; *p; p++)
  121: 		if (*p == '-')
  122: 		  *p = '.';
  123: 	    }
  124: 	  else
  125: 	    {
  126: 	      /* swap . or : for - */
  127: 	      for (p = tail; *p; p++)
  128: 		if (*p == '-')
  129: 		  {
  130: 		    if (prot == AF_INET)
  131: 		      *p = '.';
  132: 		    else
  133: 		      *p = ':';
  134: 		  }
  135: 	    }
  136: 	  
  137: 	  if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
  138: 	    {
  139: 	      if (prot == AF_INET)
  140: 		{
  141: 		  if (!c->is6 &&
  142: 		      ntohl(addr->addr4.s_addr) >= ntohl(c->start.s_addr) &&
  143: 		      ntohl(addr->addr4.s_addr) <= ntohl(c->end.s_addr))
  144: 		    found = 1;
  145: 		}
  146: 	      else
  147: 		{
  148: 		  u64 addrpart = addr6part(&addr->addr6);
  149: 		  
  150: 		  if (c->is6 &&
  151: 		      is_same_net6(&addr->addr6, &c->start6, 64) &&
  152: 		      addrpart >= addr6part(&c->start6) &&
  153: 		      addrpart <= addr6part(&c->end6))
  154: 		    found = 1;
  155: 		}
  156: 	    }
  157: 
  158: 	}
  159: 
  160:       /* restore name */
  161:       for (p = tail; *p; p++)
  162: 	if (*p == '.' || *p == ':')
  163: 	  *p = '-';
  164:       
  165:       *p = '.';
  166:       
  167:       
  168:       if (found)
  169: 	return 1;
  170:     }
  171:   
  172:   return 0;
  173: }
  174: 
  175: 
  176: int is_rev_synth(int flag, union all_addr *addr, char *name)
  177: {
  178:    struct cond_domain *c;
  179: 
  180:    if (flag & F_IPV4 && (c = search_domain(addr->addr4, daemon->synth_domains))) 
  181:      {
  182:        char *p;
  183:        
  184:        *name = 0;
  185:        if (c->indexed)
  186: 	 {
  187: 	   unsigned int index = ntohl(addr->addr4.s_addr) - ntohl(c->start.s_addr);
  188: 	   snprintf(name, MAXDNAME, "%s%u", c->prefix ? c->prefix : "", index);
  189: 	 }
  190:        else
  191: 	 {
  192: 	   if (c->prefix)
  193: 	     strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
  194:        
  195:        	   inet_ntop(AF_INET, &addr->addr4, name + strlen(name), ADDRSTRLEN);
  196: 	   for (p = name; *p; p++)
  197: 	     if (*p == '.')
  198: 	       *p = '-';
  199: 	 }
  200:        
  201:        strncat(name, ".", MAXDNAME);
  202:        strncat(name, c->domain, MAXDNAME);
  203: 
  204:        return 1;
  205:      }
  206: 
  207:    if ((flag & F_IPV6) && (c = search_domain6(&addr->addr6, daemon->synth_domains))) 
  208:      {
  209:        char *p;
  210:        
  211:        *name = 0;
  212:        if (c->indexed)
  213: 	 {
  214: 	   u64 index = addr6part(&addr->addr6) - addr6part(&c->start6);
  215: 	   snprintf(name, MAXDNAME, "%s%llu", c->prefix ? c->prefix : "", index);
  216: 	 }
  217:        else
  218: 	 {
  219: 	   if (c->prefix)
  220: 	     strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
  221:        
  222: 	   inet_ntop(AF_INET6, &addr->addr6, name + strlen(name), ADDRSTRLEN);
  223: 
  224: 	   /* IPv6 presentation address can start with ":", but valid domain names
  225: 	      cannot start with "-" so prepend a zero in that case. */
  226: 	   if (!c->prefix && *name == ':')
  227: 	     {
  228: 	       *name = '0';
  229: 	       inet_ntop(AF_INET6, &addr->addr6, name+1, ADDRSTRLEN);
  230: 	     }
  231: 	   
  232: 	   /* V4-mapped have periods.... */
  233: 	   for (p = name; *p; p++)
  234: 	     if (*p == ':' || *p == '.')
  235: 	       *p = '-';
  236: 	   
  237: 	 }
  238: 
  239:        strncat(name, ".", MAXDNAME);
  240:        strncat(name, c->domain, MAXDNAME);
  241:        
  242:        return 1;
  243:      }
  244:    
  245:    return 0;
  246: }
  247: 
  248: 
  249: static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c)
  250: {
  251:   for (; c; c = c->next)
  252:     if (!c->is6 &&
  253: 	ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
  254:         ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
  255:       return c;
  256: 
  257:   return NULL;
  258: }
  259: 
  260: char *get_domain(struct in_addr addr)
  261: {
  262:   struct cond_domain *c;
  263: 
  264:   if ((c = search_domain(addr, daemon->cond_domain)))
  265:     return c->domain;
  266: 
  267:   return daemon->domain_suffix;
  268: } 
  269: 
  270: 
  271: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
  272: {
  273:   u64 addrpart = addr6part(addr);
  274:   
  275:   for (; c; c = c->next)
  276:     if (c->is6 &&
  277: 	is_same_net6(addr, &c->start6, 64) &&
  278: 	addrpart >= addr6part(&c->start6) &&
  279:         addrpart <= addr6part(&c->end6))
  280:       return c;
  281:   
  282:   return NULL;
  283: }
  284: 
  285: char *get_domain6(struct in6_addr *addr)
  286: {
  287:   struct cond_domain *c;
  288: 
  289:   if (addr && (c = search_domain6(addr, daemon->cond_domain)))
  290:     return c->domain;
  291: 
  292:   return daemon->domain_suffix;
  293: } 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>