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

1.1.1.3 ! misho       1: /* dnsmasq is Copyright (c) 2000-2021 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);
                     21: static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c);
                     22: 
                     23: 
1.1.1.3 ! misho      24: int is_name_synthetic(int flags, char *name, union all_addr *addr)
1.1       misho      25: {
                     26:   char *p;
                     27:   struct cond_domain *c = NULL;
1.1.1.3 ! misho      28:   int prot = (flags & F_IPV6) ? AF_INET6 : AF_INET;
1.1       misho      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 */
1.1.1.3 ! misho      51: 
        !            52:       if (c->indexed)
1.1       misho      53:        {
1.1.1.3 ! misho      54:          for (p = tail; *p; p++)
        !            55:            {
        !            56:              char c = *p;
        !            57:              
        !            58:              if (c < '0' || c > '9')
        !            59:                break;
        !            60:            }
1.1       misho      61:          
1.1.1.3 ! misho      62:          if (*p != '.')
1.1       misho      63:            continue;
                     64:          
1.1.1.3 ! misho      65:          *p = 0;
1.1       misho      66:          
1.1.1.3 ! misho      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:            }
1.1       misho      94:        }
1.1.1.3 ! misho      95:       else
1.1       misho      96:        {
1.1.1.3 ! misho      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)
1.1       misho     117:            {
1.1.1.3 ! misho     118:              /* special hack for v4-mapped. */
        !           119:              memcpy(tail, "::ffff:", 7);
        !           120:              for (p = tail + 7; *p; p++)
        !           121:                if (*p == '-')
        !           122:                  *p = '.';
1.1       misho     123:            }
                    124:          else
                    125:            {
1.1.1.3 ! misho     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:                }
1.1       misho     156:            }
1.1.1.3 ! misho     157: 
1.1       misho     158:        }
1.1.1.3 ! misho     159: 
1.1       misho     160:       /* restore name */
                    161:       for (p = tail; *p; p++)
                    162:        if (*p == '.' || *p == ':')
                    163:          *p = '-';
                    164:       
                    165:       *p = '.';
1.1.1.3 ! misho     166:       
        !           167:       
1.1       misho     168:       if (found)
                    169:        return 1;
                    170:     }
                    171:   
                    172:   return 0;
                    173: }
                    174: 
                    175: 
1.1.1.3 ! misho     176: int is_rev_synth(int flag, union all_addr *addr, char *name)
1.1       misho     177: {
                    178:    struct cond_domain *c;
                    179: 
1.1.1.3 ! misho     180:    if (flag & F_IPV4 && (c = search_domain(addr->addr4, daemon->synth_domains))) 
1.1       misho     181:      {
                    182:        char *p;
                    183:        
                    184:        *name = 0;
1.1.1.3 ! misho     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:         }
1.1       misho     200:        
                    201:        strncat(name, ".", MAXDNAME);
                    202:        strncat(name, c->domain, MAXDNAME);
                    203: 
                    204:        return 1;
                    205:      }
                    206: 
1.1.1.3 ! misho     207:    if ((flag & F_IPV6) && (c = search_domain6(&addr->addr6, daemon->synth_domains))) 
1.1       misho     208:      {
                    209:        char *p;
                    210:        
                    211:        *name = 0;
1.1.1.3 ! misho     212:        if (c->indexed)
1.1       misho     213:         {
1.1.1.3 ! misho     214:           u64 index = addr6part(&addr->addr6) - addr6part(&c->start6);
        !           215:           snprintf(name, MAXDNAME, "%s%llu", c->prefix ? c->prefix : "", index);
1.1       misho     216:         }
1.1.1.3 ! misho     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);
1.1       misho     223: 
1.1.1.3 ! misho     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:         }
1.1       misho     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: 
1.1.1.3 ! misho     270: 
1.1       misho     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>