Annotation of embedaddon/dnsmasq/src/domain.c, revision 1.1.1.4

1.1.1.4 ! misho       1: /* dnsmasq is Copyright (c) 2000-2022 Simon Kelley
1.1       misho       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);
1.1.1.4 ! misho      21: static int match_domain(struct in_addr addr, struct cond_domain *c);
1.1       misho      22: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c);
1.1.1.4 ! misho      23: static int match_domain6(struct in6_addr *addr, struct cond_domain *c);
1.1       misho      24: 
1.1.1.3   misho      25: int is_name_synthetic(int flags, char *name, union all_addr *addr)
1.1       misho      26: {
                     27:   char *p;
                     28:   struct cond_domain *c = NULL;
1.1.1.3   misho      29:   int prot = (flags & F_IPV6) ? AF_INET6 : AF_INET;
1.1       misho      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 */
1.1.1.3   misho      52: 
                     53:       if (c->indexed)
1.1       misho      54:        {
1.1.1.3   misho      55:          for (p = tail; *p; p++)
                     56:            {
                     57:              char c = *p;
                     58:              
                     59:              if (c < '0' || c > '9')
                     60:                break;
                     61:            }
1.1       misho      62:          
1.1.1.3   misho      63:          if (*p != '.')
1.1       misho      64:            continue;
                     65:          
1.1.1.3   misho      66:          *p = 0;
1.1       misho      67:          
1.1.1.3   misho      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:            }
1.1       misho      95:        }
1.1.1.3   misho      96:       else
1.1       misho      97:        {
1.1.1.3   misho      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)
1.1       misho     118:            {
1.1.1.3   misho     119:              /* special hack for v4-mapped. */
                    120:              memcpy(tail, "::ffff:", 7);
                    121:              for (p = tail + 7; *p; p++)
                    122:                if (*p == '-')
                    123:                  *p = '.';
1.1       misho     124:            }
                    125:          else
                    126:            {
1.1.1.3   misho     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))
1.1.1.4 ! misho     139:            found = (prot == AF_INET) ? match_domain(addr->addr4, c) : match_domain6(&addr->addr6, c);
1.1       misho     140:        }
1.1.1.4 ! misho     141:       
1.1       misho     142:       /* restore name */
                    143:       for (p = tail; *p; p++)
                    144:        if (*p == '.' || *p == ':')
                    145:          *p = '-';
                    146:       
                    147:       *p = '.';
1.1.1.3   misho     148:       
                    149:       
1.1       misho     150:       if (found)
                    151:        return 1;
                    152:     }
                    153:   
                    154:   return 0;
                    155: }
                    156: 
                    157: 
1.1.1.3   misho     158: int is_rev_synth(int flag, union all_addr *addr, char *name)
1.1       misho     159: {
                    160:    struct cond_domain *c;
                    161: 
1.1.1.3   misho     162:    if (flag & F_IPV4 && (c = search_domain(addr->addr4, daemon->synth_domains))) 
1.1       misho     163:      {
                    164:        char *p;
                    165:        
                    166:        *name = 0;
1.1.1.3   misho     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:         }
1.1       misho     182:        
                    183:        strncat(name, ".", MAXDNAME);
                    184:        strncat(name, c->domain, MAXDNAME);
                    185: 
                    186:        return 1;
                    187:      }
                    188: 
1.1.1.3   misho     189:    if ((flag & F_IPV6) && (c = search_domain6(&addr->addr6, daemon->synth_domains))) 
1.1       misho     190:      {
                    191:        char *p;
                    192:        
                    193:        *name = 0;
1.1.1.3   misho     194:        if (c->indexed)
1.1       misho     195:         {
1.1.1.3   misho     196:           u64 index = addr6part(&addr->addr6) - addr6part(&c->start6);
                    197:           snprintf(name, MAXDNAME, "%s%llu", c->prefix ? c->prefix : "", index);
1.1       misho     198:         }
1.1.1.3   misho     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);
1.1       misho     205: 
1.1.1.3   misho     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:         }
1.1       misho     220: 
                    221:        strncat(name, ".", MAXDNAME);
                    222:        strncat(name, c->domain, MAXDNAME);
                    223:        
                    224:        return 1;
                    225:      }
                    226:    
                    227:    return 0;
                    228: }
                    229: 
                    230: 
1.1.1.4 ! misho     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: 
1.1       misho     249: static struct cond_domain *search_domain(struct in_addr addr, struct cond_domain *c)
                    250: {
                    251:   for (; c; c = c->next)
1.1.1.4 ! misho     252:     if (match_domain(addr, c))
1.1       misho     253:       return c;
1.1.1.4 ! misho     254:   
1.1       misho     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: 
1.1.1.4 ! misho     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: }
1.1.1.3   misho     296: 
1.1       misho     297: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c)
                    298: {
                    299:   for (; c; c = c->next)
1.1.1.4 ! misho     300:     if (match_domain6(addr, c))
1.1       misho     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>