File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / domain.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:02:07 2023 UTC (9 months, 1 week ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v8_2p1, HEAD
Version 8.2p1

    1: /* dnsmasq is Copyright (c) 2000-2022 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 int match_domain(struct in_addr addr, struct cond_domain *c);
   22: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c);
   23: static int match_domain6(struct in6_addr *addr, struct cond_domain *c);
   24: 
   25: int is_name_synthetic(int flags, char *name, union all_addr *addr)
   26: {
   27:   char *p;
   28:   struct cond_domain *c = NULL;
   29:   int prot = (flags & F_IPV6) ? AF_INET6 : AF_INET;
   30: 
   31:   for (c = daemon->synth_domains; c; c = c->next)
   32:     {
   33:       int found = 0;
   34:       char *tail, *pref;
   35:       
   36:       for (tail = name, pref = c->prefix; *tail != 0 && pref && *pref != 0; tail++, pref++)
   37: 	{
   38: 	  unsigned int c1 = (unsigned char) *pref;
   39: 	  unsigned int c2 = (unsigned char) *tail;
   40: 	  
   41: 	  if (c1 >= 'A' && c1 <= 'Z')
   42: 	    c1 += 'a' - 'A';
   43: 	  if (c2 >= 'A' && c2 <= 'Z')
   44: 	    c2 += 'a' - 'A';
   45: 	  
   46: 	  if (c1 != c2)
   47: 	    break;
   48: 	}
   49:       
   50:       if (pref && *pref != 0)
   51: 	continue; /* prefix match fail */
   52: 
   53:       if (c->indexed)
   54: 	{
   55: 	  for (p = tail; *p; p++)
   56: 	    {
   57: 	      char c = *p;
   58: 	      
   59: 	      if (c < '0' || c > '9')
   60: 		break;
   61: 	    }
   62: 	  
   63: 	  if (*p != '.')
   64: 	    continue;
   65: 	  
   66: 	  *p = 0;
   67: 	  
   68: 	  if (hostname_isequal(c->domain, p+1))
   69: 	    {
   70: 	      if (prot == AF_INET)
   71: 		{
   72: 		  unsigned int index = atoi(tail);
   73: 
   74: 		   if (!c->is6 &&
   75: 		      index <= ntohl(c->end.s_addr) - ntohl(c->start.s_addr))
   76: 		    {
   77: 		      addr->addr4.s_addr = htonl(ntohl(c->start.s_addr) + index);
   78: 		      found = 1;
   79: 		    }
   80: 		} 
   81: 	      else
   82: 		{
   83: 		  u64 index = atoll(tail);
   84: 		  
   85: 		  if (c->is6 &&
   86: 		      index <= addr6part(&c->end6) - addr6part(&c->start6))
   87: 		    {
   88: 		      u64 start = addr6part(&c->start6);
   89: 		      addr->addr6 = c->start6;
   90: 		      setaddr6part(&addr->addr6, start + index);
   91: 		      found = 1;
   92: 		    }
   93: 		}
   94: 	    }
   95: 	}
   96:       else
   97: 	{
   98: 	  /* NB, must not alter name if we return zero */
   99: 	  for (p = tail; *p; p++)
  100: 	    {
  101: 	      char c = *p;
  102: 	      
  103: 	      if ((c >='0' && c <= '9') || c == '-')
  104: 		continue;
  105: 	      
  106: 	      if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f'))) 
  107: 		continue;
  108: 	      
  109: 	      break;
  110: 	    }
  111: 	  
  112: 	  if (*p != '.')
  113: 	    continue;
  114: 	  
  115: 	  *p = 0;	
  116: 	  
  117: 	  if (prot == AF_INET6 && strstr(tail, "--ffff-") == tail)
  118: 	    {
  119: 	      /* special hack for v4-mapped. */
  120: 	      memcpy(tail, "::ffff:", 7);
  121: 	      for (p = tail + 7; *p; p++)
  122: 		if (*p == '-')
  123: 		  *p = '.';
  124: 	    }
  125: 	  else
  126: 	    {
  127: 	      /* swap . or : for - */
  128: 	      for (p = tail; *p; p++)
  129: 		if (*p == '-')
  130: 		  {
  131: 		    if (prot == AF_INET)
  132: 		      *p = '.';
  133: 		    else
  134: 		      *p = ':';
  135: 		  }
  136: 	    }
  137: 	  
  138: 	  if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
  139: 	    found = (prot == AF_INET) ? match_domain(addr->addr4, c) : match_domain6(&addr->addr6, c);
  140: 	}
  141:       
  142:       /* restore name */
  143:       for (p = tail; *p; p++)
  144: 	if (*p == '.' || *p == ':')
  145: 	  *p = '-';
  146:       
  147:       *p = '.';
  148:       
  149:       
  150:       if (found)
  151: 	return 1;
  152:     }
  153:   
  154:   return 0;
  155: }
  156: 
  157: 
  158: int is_rev_synth(int flag, union all_addr *addr, char *name)
  159: {
  160:    struct cond_domain *c;
  161: 
  162:    if (flag & F_IPV4 && (c = search_domain(addr->addr4, daemon->synth_domains))) 
  163:      {
  164:        char *p;
  165:        
  166:        *name = 0;
  167:        if (c->indexed)
  168: 	 {
  169: 	   unsigned int index = ntohl(addr->addr4.s_addr) - ntohl(c->start.s_addr);
  170: 	   snprintf(name, MAXDNAME, "%s%u", c->prefix ? c->prefix : "", index);
  171: 	 }
  172:        else
  173: 	 {
  174: 	   if (c->prefix)
  175: 	     strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
  176:        
  177:        	   inet_ntop(AF_INET, &addr->addr4, name + strlen(name), ADDRSTRLEN);
  178: 	   for (p = name; *p; p++)
  179: 	     if (*p == '.')
  180: 	       *p = '-';
  181: 	 }
  182:        
  183:        strncat(name, ".", MAXDNAME);
  184:        strncat(name, c->domain, MAXDNAME);
  185: 
  186:        return 1;
  187:      }
  188: 
  189:    if ((flag & F_IPV6) && (c = search_domain6(&addr->addr6, daemon->synth_domains))) 
  190:      {
  191:        char *p;
  192:        
  193:        *name = 0;
  194:        if (c->indexed)
  195: 	 {
  196: 	   u64 index = addr6part(&addr->addr6) - addr6part(&c->start6);
  197: 	   snprintf(name, MAXDNAME, "%s%llu", c->prefix ? c->prefix : "", index);
  198: 	 }
  199:        else
  200: 	 {
  201: 	   if (c->prefix)
  202: 	     strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
  203:        
  204: 	   inet_ntop(AF_INET6, &addr->addr6, name + strlen(name), ADDRSTRLEN);
  205: 
  206: 	   /* IPv6 presentation address can start with ":", but valid domain names
  207: 	      cannot start with "-" so prepend a zero in that case. */
  208: 	   if (!c->prefix && *name == ':')
  209: 	     {
  210: 	       *name = '0';
  211: 	       inet_ntop(AF_INET6, &addr->addr6, name+1, ADDRSTRLEN);
  212: 	     }
  213: 	   
  214: 	   /* V4-mapped have periods.... */
  215: 	   for (p = name; *p; p++)
  216: 	     if (*p == ':' || *p == '.')
  217: 	       *p = '-';
  218: 	   
  219: 	 }
  220: 
  221:        strncat(name, ".", MAXDNAME);
  222:        strncat(name, c->domain, MAXDNAME);
  223:        
  224:        return 1;
  225:      }
  226:    
  227:    return 0;
  228: }
  229: 
  230: 
  231: static int match_domain(struct in_addr addr, struct cond_domain *c)
  232: {
  233:   if (c->interface)
  234:     {
  235:       struct addrlist *al;
  236:       for (al = c->al; al; al = al->next)
  237: 	if (!(al->flags & ADDRLIST_IPV6) &&
  238: 	    is_same_net_prefix(addr, al->addr.addr4, al->prefixlen))
  239: 	  return 1;
  240:     }
  241:   else if (!c->is6 &&
  242: 	   ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
  243: 	   ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
  244:     return 1;
  245: 
  246:   return 0;
  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 (match_domain(addr, c))
  253:       return c;
  254:   
  255:   return NULL;
  256: }
  257: 
  258: char *get_domain(struct in_addr addr)
  259: {
  260:   struct cond_domain *c;
  261: 
  262:   if ((c = search_domain(addr, daemon->cond_domain)))
  263:     return c->domain;
  264: 
  265:   return daemon->domain_suffix;
  266: } 
  267: 
  268: static int match_domain6(struct in6_addr *addr, struct cond_domain *c)
  269: {
  270:     
  271:   /* subnet from interface address. */
  272:   if (c->interface)
  273:     {
  274:       struct addrlist *al;
  275:       for (al = c->al; al; al = al->next)
  276: 	if (al->flags & ADDRLIST_IPV6 &&
  277: 	    is_same_net6(addr, &al->addr.addr6, al->prefixlen))
  278: 	  return 1;
  279:     }
  280:   else if (c->is6)
  281:     {
  282:       if (c->prefixlen >= 64)
  283: 	{
  284: 	  u64 addrpart = addr6part(addr);
  285: 	  if (is_same_net6(addr, &c->start6, 64) &&
  286: 	      addrpart >= addr6part(&c->start6) &&
  287: 	      addrpart <= addr6part(&c->end6))
  288: 	    return 1;
  289: 	}
  290:       else if (is_same_net6(addr, &c->start6, c->prefixlen))
  291: 	return 1;
  292:     }
  293:     
  294:   return 0;
  295: }
  296: 
  297: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
  298: {
  299:   for (; c; c = c->next)
  300:     if (match_domain6(addr, c))
  301:       return c;
  302:   
  303:   return NULL;
  304: }
  305: 
  306: char *get_domain6(struct in6_addr *addr)
  307: {
  308:   struct cond_domain *c;
  309: 
  310:   if (addr && (c = search_domain6(addr, daemon->cond_domain)))
  311:     return c->domain;
  312: 
  313:   return daemon->domain_suffix;
  314: } 

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