File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / domain.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 09:57:01 2016 UTC (7 years, 8 months ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v2_76p1, HEAD
dnsmasq 2.76

    1: /* dnsmasq is Copyright (c) 2000-2016 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: #ifdef HAVE_IPV6
   22: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c);
   23: #endif
   24: 
   25: 
   26: int is_name_synthetic(int flags, char *name, struct all_addr *addr)
   27: {
   28:   char *p;
   29:   struct cond_domain *c = NULL;
   30:   int prot = AF_INET;
   31: 
   32: #ifdef HAVE_IPV6
   33:   if (flags & F_IPV6)
   34:     prot = AF_INET6;
   35: #endif
   36: 
   37:   for (c = daemon->synth_domains; c; c = c->next)
   38:     {
   39:       int found = 0;
   40:       char *tail, *pref;
   41:       
   42:       for (tail = name, pref = c->prefix; *tail != 0 && pref && *pref != 0; tail++, pref++)
   43: 	{
   44: 	  unsigned int c1 = (unsigned char) *pref;
   45: 	  unsigned int c2 = (unsigned char) *tail;
   46: 	  
   47: 	  if (c1 >= 'A' && c1 <= 'Z')
   48: 	    c1 += 'a' - 'A';
   49: 	  if (c2 >= 'A' && c2 <= 'Z')
   50: 	    c2 += 'a' - 'A';
   51: 	  
   52: 	  if (c1 != c2)
   53: 	    break;
   54: 	}
   55:       
   56:       if (pref && *pref != 0)
   57: 	continue; /* prefix match fail */
   58:       
   59:       /* NB, must not alter name if we return zero */
   60:       for (p = tail; *p; p++)
   61: 	{
   62: 	  char c = *p;
   63: 	  
   64: 	  if ((c >='0' && c <= '9') || c == '-')
   65: 	    continue;
   66: 	  
   67: #ifdef HAVE_IPV6
   68: 	  if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f'))) 
   69: 	    continue;
   70: #endif
   71: 	  
   72: 	  break;
   73: 	}
   74:       
   75:       if (*p != '.')
   76: 	continue;
   77:       
   78:       *p = 0;	
   79:       
   80:       /* swap . or : for - */
   81:       for (p = tail; *p; p++)
   82: 	if (*p == '-')
   83: 	  {
   84: 	    if (prot == AF_INET)
   85: 	      *p = '.';
   86: #ifdef HAVE_IPV6
   87: 	    else
   88: 	      *p = ':';
   89: #endif
   90: 	  }
   91:       
   92:       if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
   93: 	{
   94: 	  if (prot == AF_INET)
   95: 	    {
   96: 	      if (!c->is6 &&
   97: 		  ntohl(addr->addr.addr4.s_addr) >= ntohl(c->start.s_addr) &&
   98: 		  ntohl(addr->addr.addr4.s_addr) <= ntohl(c->end.s_addr))
   99: 		found = 1;
  100: 	    }
  101: #ifdef HAVE_IPV6
  102: 	  else
  103: 	    {
  104: 	      u64 addrpart = addr6part(&addr->addr.addr6);
  105: 	      
  106: 	      if (c->is6 &&
  107: 		  is_same_net6(&addr->addr.addr6, &c->start6, 64) &&
  108: 		  addrpart >= addr6part(&c->start6) &&
  109: 		  addrpart <= addr6part(&c->end6))
  110: 		found = 1;
  111: 	    }
  112: #endif
  113: 	}
  114:       
  115:       /* restore name */
  116:       for (p = tail; *p; p++)
  117: 	if (*p == '.' || *p == ':')
  118: 	  *p = '-';
  119:       
  120:       *p = '.';
  121: 
  122:       if (found)
  123: 	return 1;
  124:     }
  125:   
  126:   return 0;
  127: }
  128: 
  129: 
  130: int is_rev_synth(int flag, struct all_addr *addr, char *name)
  131: {
  132:    struct cond_domain *c;
  133: 
  134:    if (flag & F_IPV4 && (c = search_domain(addr->addr.addr4, daemon->synth_domains))) 
  135:      {
  136:        char *p;
  137:        
  138:        *name = 0;
  139:        if (c->prefix)
  140: 	 strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
  141:        
  142:        inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN);
  143:        for (p = name; *p; p++)
  144: 	 if (*p == '.')
  145: 	   *p = '-';
  146: 
  147:        strncat(name, ".", MAXDNAME);
  148:        strncat(name, c->domain, MAXDNAME);
  149: 
  150:        return 1;
  151:      }
  152: 
  153: #ifdef HAVE_IPV6
  154:    if (flag & F_IPV6 && (c = search_domain6(&addr->addr.addr6, daemon->synth_domains))) 
  155:      {
  156:        char *p;
  157:        
  158:        *name = 0;
  159:        if (c->prefix)
  160: 	 strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
  161:        
  162:        inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN);
  163: 
  164:        /* IPv6 presentation address can start with ":", but valid domain names
  165: 	  cannot start with "-" so prepend a zero in that case. */
  166:        if (!c->prefix && *name == ':')
  167: 	 {
  168: 	   *name = '0';
  169: 	   inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN);
  170: 	 }
  171: 
  172:        for (p = name; *p; p++)
  173: 	 if (*p == ':')
  174: 	   *p = '-';
  175: 
  176:        strncat(name, ".", MAXDNAME);
  177:        strncat(name, c->domain, MAXDNAME);
  178:        
  179:        return 1;
  180:      }
  181: #endif
  182:    
  183:    return 0;
  184: }
  185: 
  186: 
  187: static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c)
  188: {
  189:   for (; c; c = c->next)
  190:     if (!c->is6 &&
  191: 	ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
  192:         ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
  193:       return c;
  194: 
  195:   return NULL;
  196: }
  197: 
  198: char *get_domain(struct in_addr addr)
  199: {
  200:   struct cond_domain *c;
  201: 
  202:   if ((c = search_domain(addr, daemon->cond_domain)))
  203:     return c->domain;
  204: 
  205:   return daemon->domain_suffix;
  206: } 
  207: 
  208: #ifdef HAVE_IPV6
  209: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
  210: {
  211:   u64 addrpart = addr6part(addr);
  212:   
  213:   for (; c; c = c->next)
  214:     if (c->is6 &&
  215: 	is_same_net6(addr, &c->start6, 64) &&
  216: 	addrpart >= addr6part(&c->start6) &&
  217:         addrpart <= addr6part(&c->end6))
  218:       return c;
  219:   
  220:   return NULL;
  221: }
  222: 
  223: char *get_domain6(struct in6_addr *addr)
  224: {
  225:   struct cond_domain *c;
  226: 
  227:   if (addr && (c = search_domain6(addr, daemon->cond_domain)))
  228:     return c->domain;
  229: 
  230:   return daemon->domain_suffix;
  231: } 
  232: #endif

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