Diff for /embedaddon/dnsmasq/src/dhcp-common.c between versions 1.1.1.4 and 1.1.1.5

version 1.1.1.4, 2021/03/17 00:56:46 version 1.1.1.5, 2023/09/27 11:02:07
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley/* dnsmasq is Copyright (c) 2000-2022 Simon Kelley
   
    This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
Line 79  ssize_t recv_dhcp_packet(int fd, struct msghdr *msg) Line 79  ssize_t recv_dhcp_packet(int fd, struct msghdr *msg)
   return (msg->msg_flags & MSG_TRUNC) ? -1 : new_sz;    return (msg->msg_flags & MSG_TRUNC) ? -1 : new_sz;
 }  }
   
   /* like match_netid() except that the check can have a trailing * for wildcard */
   /* started as a direct copy of match_netid() */
   int match_netid_wild(struct dhcp_netid *check, struct dhcp_netid *pool)
   {
     struct dhcp_netid *tmp1;
     
     for (; check; check = check->next)
       {
         const int check_len = strlen(check->net);
         const int is_wc = (check_len > 0 && check->net[check_len - 1] == '*');
         
         /* '#' for not is for backwards compat. */
         if (check->net[0] != '!' && check->net[0] != '#')
           {
             for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
               if (is_wc ? (strncmp(check->net, tmp1->net, check_len-1) == 0) :
                   (strcmp(check->net, tmp1->net) == 0))
                 break;
             if (!tmp1)
               return 0;
           }
         else
           for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
             if (is_wc ? (strncmp((check->net)+1, tmp1->net, check_len-2) == 0) :
                 (strcmp((check->net)+1, tmp1->net) == 0))
               return 0;
       }
     return 1;
   }
   
 struct dhcp_netid *run_tag_if(struct dhcp_netid *tags)  struct dhcp_netid *run_tag_if(struct dhcp_netid *tags)
 {  {
   struct tag_if *exprs;    struct tag_if *exprs;
   struct dhcp_netid_list *list;    struct dhcp_netid_list *list;
   
     /* this now uses match_netid_wild() above so that tag_if can
      * be used to set a 'group of interfaces' tag.
      */
   for (exprs = daemon->tag_if; exprs; exprs = exprs->next)    for (exprs = daemon->tag_if; exprs; exprs = exprs->next)
    if (match_netid(exprs->tag, tags, 1))    if (match_netid_wild(exprs->tag, tags))
       for (list = exprs->set; list; list = list->next)        for (list = exprs->set; list; list = list->next)
         {          {
           list->list->next = tags;            list->list->next = tags;
Line 280  static int is_config_in_context(struct dhcp_context *c Line 313  static int is_config_in_context(struct dhcp_context *c
 {  {
   if (!context) /* called via find_config() from lease_update_from_configs() */    if (!context) /* called via find_config() from lease_update_from_configs() */
     return 1;       return 1; 
   
     if (!(config->flags & (CONFIG_ADDR | CONFIG_ADDR6)))
       return 1;
       
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
   if (context->flags & CONTEXT_V6)    if (context->flags & CONTEXT_V6)
     {      {
        struct addrlist *addr_list;         struct addrlist *addr_list;
   
       if (!(config->flags & CONFIG_ADDR6))       if (config->flags & CONFIG_ADDR6)
         return 1;         for (; context; context = context->current)
                  for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
        for (; context; context = context->current)             {
          for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)               if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64)
            {                 return 1;
              if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64)               
                return 1;               if (is_same_net6(&addr_list->addr.addr6, &context->start6, context->prefix))
                               return 1;
              if (is_same_net6(&addr_list->addr.addr6, &context->start6, context->prefix))             }
                return 1; 
            } 
     }      }
   else    else
 #endif  #endif
     {      {
       if (!(config->flags & CONFIG_ADDR))  
         return 1;  
         
       for (; context; context = context->current)        for (; context; context = context->current)
         if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask))          if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask))
           return 1;            return 1;
Line 535  char *whichdevice(void) Line 566  char *whichdevice(void)
       }        }
   
   if (found)    if (found)
    return found->name;    {
      char *ret = safe_malloc(strlen(found->name)+1);
       strcpy(ret, found->name);
       return ret;
     }
   
   return NULL;    return NULL;
 }  }
     
void  bindtodevice(char *device, int fd)static int bindtodevice(char *device, int fd)
 {  {
   size_t len = strlen(device)+1;    size_t len = strlen(device)+1;
   if (len > IFNAMSIZ)    if (len > IFNAMSIZ)
Line 548  void  bindtodevice(char *device, int fd) Line 583  void  bindtodevice(char *device, int fd)
   /* only allowed by root. */    /* only allowed by root. */
   if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, len) == -1 &&    if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, len) == -1 &&
       errno != EPERM)        errno != EPERM)
    die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);    return 2;
   
   return 1;
 }  }
   
   int bind_dhcp_devices(char *bound_device)
   {
     int ret = 0;
   
     if (bound_device)
       {
         if (daemon->dhcp)
           {
             if (!daemon->relay4)
               ret |= bindtodevice(bound_device, daemon->dhcpfd);
             
             if (daemon->enable_pxe && daemon->pxefd != -1)
               ret |= bindtodevice(bound_device, daemon->pxefd);
           }
         
   #if defined(HAVE_DHCP6)
         if (daemon->doing_dhcp6 && !daemon->relay6)
           ret |= bindtodevice(bound_device, daemon->dhcp6fd);
 #endif  #endif
       }
     
     return ret;
   }
   #endif
   
 static const struct opttab_t {  static const struct opttab_t {
   char *name;    char *name;
Line 622  static const struct opttab_t { Line 683  static const struct opttab_t {
   { "client-arch", 93, 2 | OT_DEC },    { "client-arch", 93, 2 | OT_DEC },
   { "client-interface-id", 94, 0 },    { "client-interface-id", 94, 0 },
   { "client-machine-id", 97, 0 },    { "client-machine-id", 97, 0 },
     { "posix-timezone", 100, OT_NAME }, /* RFC 4833, Sec. 2 */
     { "tzdb-timezone", 101, OT_NAME }, /* RFC 4833, Sec. 2 */
     { "ipv6-only", 108, 4 | OT_DEC },  /* RFC 8925 */ 
   { "subnet-select", 118, OT_INTERNAL },    { "subnet-select", 118, OT_INTERNAL },
   { "domain-search", 119, OT_RFC1035_NAME },    { "domain-search", 119, OT_RFC1035_NAME },
   { "sip-server", 120, 0 },    { "sip-server", 120, 0 },
Line 658  static const struct opttab_t opttab6[] = { Line 722  static const struct opttab_t opttab6[] = {
   { "sntp-server", 31,  OT_ADDR_LIST },    { "sntp-server", 31,  OT_ADDR_LIST },
   { "information-refresh-time", 32, OT_TIME },    { "information-refresh-time", 32, OT_TIME },
   { "FQDN", 39, OT_INTERNAL | OT_RFC1035_NAME },    { "FQDN", 39, OT_INTERNAL | OT_RFC1035_NAME },
     { "posix-timezone", 41, OT_NAME }, /* RFC 4833, Sec. 3 */
     { "tzdb-timezone", 42, OT_NAME }, /* RFC 4833, Sec. 3 */
   { "ntp-server", 56, 0 /* OT_ADDR_LIST | OT_RFC1035_NAME */ },    { "ntp-server", 56, 0 /* OT_ADDR_LIST | OT_RFC1035_NAME */ },
   { "bootfile-url", 59, OT_NAME },    { "bootfile-url", 59, OT_NAME },
   { "bootfile-param", 60, OT_CSTRING },    { "bootfile-param", 60, OT_CSTRING },
Line 772  char *option_string(int prot, unsigned int opt, unsign Line 838  char *option_string(int prot, unsigned int opt, unsign
                 for (i = 0, j = 0; i < opt_len && j < buf_len ; i++)                  for (i = 0, j = 0; i < opt_len && j < buf_len ; i++)
                   {                    {
                     char c = val[i];                      char c = val[i];
                    if (isprint((int)c))                    if (isprint((unsigned char)c))
                       buf[j++] = c;                        buf[j++] = c;
                   }                    }
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
Line 786  char *option_string(int prot, unsigned int opt, unsign Line 852  char *option_string(int prot, unsigned int opt, unsign
                     for (k = i + 1; k < opt_len && k < l && j < buf_len ; k++)                      for (k = i + 1; k < opt_len && k < l && j < buf_len ; k++)
                      {                       {
                        char c = val[k];                         char c = val[k];
                       if (isprint((int)c))                       if (isprint((unsigned char)c))
                          buf[j++] = c;                           buf[j++] = c;
                      }                       }
                     i = l;                      i = l;
Line 807  char *option_string(int prot, unsigned int opt, unsign Line 873  char *option_string(int prot, unsigned int opt, unsign
                     for (k = 0; k < len && j < buf_len; k++)                      for (k = 0; k < len && j < buf_len; k++)
                       {                        {
                        char c = *p++;                         char c = *p++;
                       if (isprint((int)c))                       if (isprint((unsigned char)c))
                          buf[j++] = c;                           buf[j++] = c;
                      }                       }
                     i += len +2;                      i += len +2;
Line 952  void log_context(int family, struct dhcp_context *cont Line 1018  void log_context(int family, struct dhcp_context *cont
   
 void log_relay(int family, struct dhcp_relay *relay)  void log_relay(int family, struct dhcp_relay *relay)
 {  {
     int broadcast = relay->server.addr4.s_addr == 0;
   inet_ntop(family, &relay->local, daemon->addrbuff, ADDRSTRLEN);    inet_ntop(family, &relay->local, daemon->addrbuff, ADDRSTRLEN);
  inet_ntop(family, &relay->server, daemon->namebuff, ADDRSTRLEN);   inet_ntop(family, &relay->server, daemon->namebuff, ADDRSTRLEN);
   
     if (family == AF_INET && relay->port != DHCP_SERVER_PORT)
       sprintf(daemon->namebuff + strlen(daemon->namebuff), "#%u", relay->port);
   
   #ifdef HAVE_DHCP6
     struct in6_addr multicast;
   
     inet_pton(AF_INET6, ALL_SERVERS, &multicast);
   
     if (family == AF_INET6)
       {
         broadcast = IN6_ARE_ADDR_EQUAL(&relay->server.addr6, &multicast);
         if (relay->port != DHCPV6_SERVER_PORT)
           sprintf(daemon->namebuff + strlen(daemon->namebuff), "#%u", relay->port);
       }
   #endif
     
     
   if (relay->interface)    if (relay->interface)
    my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay from %s to %s via %s"), daemon->addrbuff, daemon->namebuff, relay->interface);    {
       if (broadcast)
         my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay from %s via %s"), daemon->addrbuff, relay->interface);
       else
         my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay from %s to %s via %s"), daemon->addrbuff, daemon->namebuff, relay->interface);
     }
   else    else
     my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay from %s to %s"), daemon->addrbuff, daemon->namebuff);      my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay from %s to %s"), daemon->addrbuff, daemon->namebuff);
 }  }

Removed from v.1.1.1.4  
changed lines
  Added in v.1.1.1.5


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