Diff for /embedaddon/dnsmasq/src/helper.c between versions 1.1 and 1.1.1.2

version 1.1, 2013/07/29 19:37:40 version 1.1.1.2, 2014/06/15 16:31:38
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2013 Simon Kelley/* dnsmasq is Copyright (c) 2000-2014 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 61  struct script_data Line 61  struct script_data
 #else  #else
   time_t expires;    time_t expires;
 #endif  #endif
   #ifdef HAVE_TFTP
     off_t file_len;
   #endif
   #ifdef HAVE_IPV6
     struct in6_addr addr6;
   #endif
   #ifdef HAVE_DHCP6
     int iaid, vendorclass_count;
   #endif
   unsigned char hwaddr[DHCP_CHADDR_MAX];    unsigned char hwaddr[DHCP_CHADDR_MAX];
   char interface[IF_NAMESIZE];    char interface[IF_NAMESIZE];
   
 };  };
   
 static struct script_data *buf = NULL;  static struct script_data *buf = NULL;
Line 215  int create_helper(int event_fd, int err_fd, uid_t uid, Line 223  int create_helper(int event_fd, int err_fd, uid_t uid,
         continue;          continue;
   
                   
      if (!is6)      /* stringify MAC into dhcp_buff */
       p = daemon->dhcp_buff;
       if (data.hwaddr_type != ARPHRD_ETHER || data.hwaddr_len == 0) 
         p += sprintf(p, "%.2x-", data.hwaddr_type);
       for (i = 0; (i < data.hwaddr_len) && (i < DHCP_CHADDR_MAX); i++)
         {          {
          /* stringify MAC into dhcp_buff */          p += sprintf(p, "%.2x", data.hwaddr[i]);
          p = daemon->dhcp_buff;          if (i != data.hwaddr_len - 1)
          if (data.hwaddr_type != ARPHRD_ETHER || data.hwaddr_len == 0)             p += sprintf(p, ":");
            p += sprintf(p, "%.2x-", data.hwaddr_type); 
          for (i = 0; (i < data.hwaddr_len) && (i < DHCP_CHADDR_MAX); i++) 
            { 
              p += sprintf(p, "%.2x", data.hwaddr[i]); 
              if (i != data.hwaddr_len - 1) 
                p += sprintf(p, ":"); 
            } 
         }          }
             
       /* supplied data may just exceed normal buffer (unlikely) */        /* supplied data may just exceed normal buffer (unlikely) */
       if ((data.hostname_len + data.ed_len + data.clid_len) > MAXDNAME &&         if ((data.hostname_len + data.ed_len + data.clid_len) > MAXDNAME && 
           !(alloc_buff = buf = malloc(data.hostname_len + data.ed_len + data.clid_len)))            !(alloc_buff = buf = malloc(data.hostname_len + data.ed_len + data.clid_len)))
Line 239  int create_helper(int event_fd, int err_fd, uid_t uid, Line 244  int create_helper(int event_fd, int err_fd, uid_t uid,
         continue;          continue;
   
       /* CLID into packet */        /* CLID into packet */
      if (!is6)      for (p = daemon->packet, i = 0; i < data.clid_len; i++)
        for (p = daemon->packet, i = 0; i < data.clid_len; i++)        {
          {          p += sprintf(p, "%.2x", buf[i]);
            p += sprintf(p, "%.2x", buf[i]);          if (i != data.clid_len - 1) 
            if (i != data.clid_len - 1)  
               p += sprintf(p, ":");                p += sprintf(p, ":");
          }        }
 
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
      else      if (is6)
         {          {
           /* or IAID and server DUID for IPv6 */            /* or IAID and server DUID for IPv6 */
          sprintf(daemon->dhcp_buff3, "%s%u", data.flags & LEASE_TA ? "T" : "", data.hwaddr_type);                sprintf(daemon->dhcp_buff3, "%s%u", data.flags & LEASE_TA ? "T" : "", data.iaid);      
          for (p = daemon->packet, i = 0; i < daemon->duid_len; i++)          for (p = daemon->dhcp_packet.iov_base, i = 0; i < daemon->duid_len; i++)
             {              {
               p += sprintf(p, "%.2x", daemon->duid[i]);                p += sprintf(p, "%.2x", daemon->duid[i]);
               if (i != daemon->duid_len - 1)                 if (i != daemon->duid_len - 1) 
                 p += sprintf(p, ":");                  p += sprintf(p, ":");
             }              }
   
           /* duid not MAC for IPv6 */  
           for (p = daemon->dhcp_buff, i = 0; i < data.clid_len; i++)  
             {  
               p += sprintf(p, "%.2x", buf[i]);  
               if (i != data.clid_len - 1)   
                 p += sprintf(p, ":");  
             }   
         }          }
 #endif  #endif
   
Line 293  int create_helper(int event_fd, int err_fd, uid_t uid, Line 291  int create_helper(int event_fd, int err_fd, uid_t uid,
         inet_ntop(AF_INET, &data.addr, daemon->addrbuff, ADDRSTRLEN);          inet_ntop(AF_INET, &data.addr, daemon->addrbuff, ADDRSTRLEN);
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
       else        else
        inet_ntop(AF_INET6, &data.hwaddr, daemon->addrbuff, ADDRSTRLEN);        inet_ntop(AF_INET6, &data.addr6, daemon->addrbuff, ADDRSTRLEN);
 #endif  #endif
   
   #ifdef HAVE_TFTP
       /* file length */        /* file length */
       if (data.action == ACTION_TFTP)        if (data.action == ACTION_TFTP)
        sprintf(daemon->dhcp_buff, "%u", data.hwaddr_len);        sprintf(is6 ? daemon->packet : daemon->dhcp_buff, "%lu", (unsigned long)data.file_len);
      #endif
 
 #ifdef HAVE_LUASCRIPT  #ifdef HAVE_LUASCRIPT
       if (daemon->luascript)        if (daemon->luascript)
         {          {
Line 316  int create_helper(int event_fd, int err_fd, uid_t uid, Line 316  int create_helper(int event_fd, int err_fd, uid_t uid,
                   lua_setfield(lua, -2, "destination_address");                    lua_setfield(lua, -2, "destination_address");
                   lua_pushstring(lua, hostname);                    lua_pushstring(lua, hostname);
                   lua_setfield(lua, -2, "file_name");                     lua_setfield(lua, -2, "file_name"); 
                  lua_pushstring(lua, daemon->dhcp_buff);                  lua_pushstring(lua, is6 ? daemon->packet : daemon->dhcp_buff);
                   lua_setfield(lua, -2, "file_size");                    lua_setfield(lua, -2, "file_size");
                   lua_call(lua, 2, 0);  /* pass 2 values, expect 0 */                    lua_call(lua, 2, 0);  /* pass 2 values, expect 0 */
                 }                  }
Line 329  int create_helper(int event_fd, int err_fd, uid_t uid, Line 329  int create_helper(int event_fd, int err_fd, uid_t uid,
                               
               if (is6)                if (is6)
                 {                  {
                   lua_pushstring(lua, daemon->dhcp_buff);  
                   lua_setfield(lua, -2, "client_duid");  
                   lua_pushstring(lua, daemon->packet);                    lua_pushstring(lua, daemon->packet);
                     lua_setfield(lua, -2, "client_duid");
                     lua_pushstring(lua, daemon->dhcp_packet.iov_base);
                   lua_setfield(lua, -2, "server_duid");                    lua_setfield(lua, -2, "server_duid");
                   lua_pushstring(lua, daemon->dhcp_buff3);                    lua_pushstring(lua, daemon->dhcp_buff3);
                   lua_setfield(lua, -2, "iaid");                    lua_setfield(lua, -2, "iaid");
Line 375  int create_helper(int event_fd, int err_fd, uid_t uid, Line 375  int create_helper(int event_fd, int err_fd, uid_t uid,
               if (!is6)                if (!is6)
                 buf = grab_extradata_lua(buf, end, "vendor_class");                  buf = grab_extradata_lua(buf, end, "vendor_class");
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
              else              else  if (data.vendorclass_count != 0)
                for (i = 0; i < data.hwaddr_len; i++)                {
                  {                  sprintf(daemon->dhcp_buff2, "vendor_class_id");
                    sprintf(daemon->dhcp_buff2, "vendor_class%i", i);                  buf = grab_extradata_lua(buf, end, daemon->dhcp_buff2);
                    buf = grab_extradata_lua(buf, end, daemon->dhcp_buff2);                  for (i = 0; i < data.vendorclass_count - 1; i++)
                  }                    {
                       sprintf(daemon->dhcp_buff2, "vendor_class%i", i);
                       buf = grab_extradata_lua(buf, end, daemon->dhcp_buff2);
                     }
                 }
 #endif  #endif
                               
               buf = grab_extradata_lua(buf, end, "supplied_hostname");                buf = grab_extradata_lua(buf, end, "supplied_hostname");
Line 423  int create_helper(int event_fd, int err_fd, uid_t uid, Line 427  int create_helper(int event_fd, int err_fd, uid_t uid,
                   lua_setfield(lua, -2, "old_hostname");                    lua_setfield(lua, -2, "old_hostname");
                 }                  }
                               
              if (!is6)              if (!is6 || data.hwaddr_len != 0)
                 {                  {
                   lua_pushstring(lua, daemon->dhcp_buff);                    lua_pushstring(lua, daemon->dhcp_buff);
                   lua_setfield(lua, -2, "mac_address");                    lua_setfield(lua, -2, "mac_address");
Line 476  int create_helper(int event_fd, int err_fd, uid_t uid, Line 480  int create_helper(int event_fd, int err_fd, uid_t uid,
               
       if (data.action != ACTION_TFTP)        if (data.action != ACTION_TFTP)
         {          {
          if (is6)#ifdef HAVE_DHCP6
            {          my_setenv("DNSMASQ_IAID", is6 ? daemon->dhcp_buff3 : NULL, &err);
              my_setenv("DNSMASQ_IAID", daemon->dhcp_buff3, &err);          my_setenv("DNSMASQ_SERVER_DUID", is6 ? daemon->dhcp_packet.iov_base : NULL, &err); 
              my_setenv("DNSMASQ_SERVER_DUID", daemon->packet, &err);          my_setenv("DNSMASQ_MAC", is6 && data.hwaddr_len != 0 ? daemon->dhcp_buff : NULL, &err);
            }#endif
                       
          if (!is6 && data.clid_len != 0)          my_setenv("DNSMASQ_CLIENT_ID", !is6 && data.clid_len != 0 ? daemon->packet : NULL, &err);
            my_setenv("DNSMASQ_CLIENT_ID", daemon->packet, &err);          my_setenv("DNSMASQ_INTERFACE", strlen(data.interface) != 0 ? data.interface : NULL, &err);
                       
           if (strlen(data.interface) != 0)  
             my_setenv("DNSMASQ_INTERFACE", data.interface, &err);  
             
 #ifdef HAVE_BROKEN_RTC  #ifdef HAVE_BROKEN_RTC
           sprintf(daemon->dhcp_buff2, "%u", data.length);            sprintf(daemon->dhcp_buff2, "%u", data.length);
           my_setenv("DNSMASQ_LEASE_LENGTH", daemon->dhcp_buff2, &err);            my_setenv("DNSMASQ_LEASE_LENGTH", daemon->dhcp_buff2, &err);
Line 496  int create_helper(int event_fd, int err_fd, uid_t uid, Line 497  int create_helper(int event_fd, int err_fd, uid_t uid,
           my_setenv("DNSMASQ_LEASE_EXPIRES", daemon->dhcp_buff2, &err);             my_setenv("DNSMASQ_LEASE_EXPIRES", daemon->dhcp_buff2, &err); 
 #endif  #endif
                       
          if (domain)          my_setenv("DNSMASQ_DOMAIN", domain, &err);
            my_setenv("DNSMASQ_DOMAIN", domain, &err); 
                       
           end = extradata + data.ed_len;            end = extradata + data.ed_len;
           buf = extradata;            buf = extradata;
Line 507  int create_helper(int event_fd, int err_fd, uid_t uid, Line 507  int create_helper(int event_fd, int err_fd, uid_t uid,
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
           else            else
             {              {
              if (data.hwaddr_len != 0)              if (data.vendorclass_count != 0)
                 {                  {
                   buf = grab_extradata(buf, end, "DNSMASQ_VENDOR_CLASS_ID", &err);                    buf = grab_extradata(buf, end, "DNSMASQ_VENDOR_CLASS_ID", &err);
                  for (i = 0; i < data.hwaddr_len - 1; i++)                  for (i = 0; i < data.vendorclass_count - 1; i++)
                     {                      {
                       sprintf(daemon->dhcp_buff2, "DNSMASQ_VENDOR_CLASS%i", i);                        sprintf(daemon->dhcp_buff2, "DNSMASQ_VENDOR_CLASS%i", i);
                       buf = grab_extradata(buf, end, daemon->dhcp_buff2, &err);                        buf = grab_extradata(buf, end, daemon->dhcp_buff2, &err);
Line 535  int create_helper(int event_fd, int err_fd, uid_t uid, Line 535  int create_helper(int event_fd, int err_fd, uid_t uid,
   
           if (is6)            if (is6)
             buf = grab_extradata(buf, end, "DNSMASQ_RELAY_ADDRESS", &err);              buf = grab_extradata(buf, end, "DNSMASQ_RELAY_ADDRESS", &err);
          else if (data.giaddr.s_addr != 0)          else 
            my_setenv("DNSMASQ_RELAY_ADDRESS", inet_ntoa(data.giaddr), &err);             my_setenv("DNSMASQ_RELAY_ADDRESS", data.giaddr.s_addr != 0 ? inet_ntoa(data.giaddr) : NULL, &err); 
                       
           for (i = 0; buf; i++)            for (i = 0; buf; i++)
             {              {
Line 544  int create_helper(int event_fd, int err_fd, uid_t uid, Line 544  int create_helper(int event_fd, int err_fd, uid_t uid,
               buf = grab_extradata(buf, end, daemon->dhcp_buff2, &err);                buf = grab_extradata(buf, end, daemon->dhcp_buff2, &err);
             }              }
                       
          if (data.action != ACTION_DEL && data.remaining_time != 0)          sprintf(daemon->dhcp_buff2, "%u", data.remaining_time);
            {          my_setenv("DNSMASQ_TIME_REMAINING", data.action != ACTION_DEL && data.remaining_time != 0 ? daemon->dhcp_buff2 : NULL, &err);
              sprintf(daemon->dhcp_buff2, "%u", data.remaining_time); 
              my_setenv("DNSMASQ_TIME_REMAINING", daemon->dhcp_buff2, &err); 
            } 
                       
          if (data.action == ACTION_OLD_HOSTNAME && hostname)          my_setenv("DNSMASQ_OLD_HOSTNAME", data.action == ACTION_OLD_HOSTNAME ? hostname : NULL, &err);
            {          if (data.action == ACTION_OLD_HOSTNAME)
              my_setenv("DNSMASQ_OLD_HOSTNAME", hostname, &err);            hostname = NULL;
              hostname = NULL; 
            } 
         }          }
   
      if (option_bool(OPT_LOG_OPTS))      my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &err);
        my_setenv("DNSMASQ_LOG_DHCP", "1", &err);      
          
       /* we need to have the event_fd around if exec fails */        /* we need to have the event_fd around if exec fails */
       if ((i = fcntl(event_fd, F_GETFD)) != -1)        if ((i = fcntl(event_fd, F_GETFD)) != -1)
         fcntl(event_fd, F_SETFD, i | FD_CLOEXEC);          fcntl(event_fd, F_SETFD, i | FD_CLOEXEC);
Line 570  int create_helper(int event_fd, int err_fd, uid_t uid, Line 564  int create_helper(int event_fd, int err_fd, uid_t uid,
         {          {
           execl(daemon->lease_change_command,             execl(daemon->lease_change_command, 
                 p ? p+1 : daemon->lease_change_command,                  p ? p+1 : daemon->lease_change_command,
                action_str, daemon->dhcp_buff, daemon->addrbuff, hostname, (char*)NULL);                action_str, is6 ? daemon->packet : daemon->dhcp_buff, 
                 daemon->addrbuff, hostname, (char*)NULL);
           err = errno;            err = errno;
         }          }
       /* failed, send event so the main process logs the problem */        /* failed, send event so the main process logs the problem */
Line 581  int create_helper(int event_fd, int err_fd, uid_t uid, Line 576  int create_helper(int event_fd, int err_fd, uid_t uid,
   
 static void my_setenv(const char *name, const char *value, int *error)  static void my_setenv(const char *name, const char *value, int *error)
 {  {
  if (*error == 0 && setenv(name, value, 1) != 0)  if (*error == 0)
    *error = errno;    {
       if (!value)
         unsetenv(name);
       else if (setenv(name, value, 1) != 0)
         *error = errno;
     }
 }  }
     
 static unsigned char *grab_extradata(unsigned char *buf, unsigned char *end,  char *env, int *err)  static unsigned char *grab_extradata(unsigned char *buf, unsigned char *end,  char *env, int *err)
 {  {
  unsigned char *next;  unsigned char *next = NULL;
   char *val = NULL;
   
  if (!buf || (buf == end))  if (buf && (buf != end))
    return NULL; 
 
  for (next = buf; *next != 0; next++) 
    if (next == end) 
      return NULL; 
   
  if (next != buf) 
     {      {
      char *p;      for (next = buf; ; next++)
      /* No "=" in value */        if (next == end)
      if ((p = strchr((char *)buf, '=')))          {
        *p = 0;            next = NULL;
      my_setenv(env, (char *)buf, err);            break;
    }          }
         else if (*next == 0)
           break;
   
  return next + 1;      if (next && (next != buf))
         {
           char *p;
           /* No "=" in value */
           if ((p = strchr((char *)buf, '=')))
             *p = 0;
           val = (char *)buf;
         }
     }
   
   my_setenv(env, val, err);
    
   return next ? next + 1 : NULL;
 }  }
   
 #ifdef HAVE_LUASCRIPT  #ifdef HAVE_LUASCRIPT
Line 656  void queue_script(int action, struct dhcp_lease *lease Line 664  void queue_script(int action, struct dhcp_lease *lease
   unsigned int hostname_len = 0, clid_len = 0, ed_len = 0;    unsigned int hostname_len = 0, clid_len = 0, ed_len = 0;
   int fd = daemon->dhcpfd;    int fd = daemon->dhcpfd;
 #ifdef HAVE_DHCP6   #ifdef HAVE_DHCP6 
   int is6 = !!(lease->flags & (LEASE_TA | LEASE_NA));  
   
   if (!daemon->dhcp)    if (!daemon->dhcp)
     fd = daemon->dhcp6fd;      fd = daemon->dhcp6fd;
 #endif  #endif
Line 678  void queue_script(int action, struct dhcp_lease *lease Line 684  void queue_script(int action, struct dhcp_lease *lease
   buf->action = action;    buf->action = action;
   buf->flags = lease->flags;    buf->flags = lease->flags;
 #ifdef HAVE_DHCP6   #ifdef HAVE_DHCP6 
  if (is6)  buf->vendorclass_count = lease->vendorclass_count;
    buf->hwaddr_len = lease->vendorclass_count;  buf->addr6 = lease->addr6;
  else  buf->iaid = lease->iaid;
 #endif  #endif
    buf->hwaddr_len = lease->hwaddr_len;  buf->hwaddr_len = lease->hwaddr_len;
   buf->hwaddr_type = lease->hwaddr_type;    buf->hwaddr_type = lease->hwaddr_type;
   buf->clid_len = clid_len;    buf->clid_len = clid_len;
   buf->ed_len = ed_len;    buf->ed_len = ed_len;
Line 739  void queue_tftp(off_t file_len, char *filename, union  Line 745  void queue_tftp(off_t file_len, char *filename, union 
   
   buf->action = ACTION_TFTP;    buf->action = ACTION_TFTP;
   buf->hostname_len = filename_len;    buf->hostname_len = filename_len;
  buf->hwaddr_len = file_len;  buf->file_len = file_len;
   
   if ((buf->flags = peer->sa.sa_family) == AF_INET)    if ((buf->flags = peer->sa.sa_family) == AF_INET)
     buf->addr = peer->in.sin_addr;      buf->addr = peer->in.sin_addr;
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
   else    else
    memcpy(buf->hwaddr, &peer->in6.sin6_addr, IN6ADDRSZ);    buf->addr6 = peer->in6.sin6_addr;
 #endif  #endif
   
   memcpy((unsigned char *)(buf+1), filename, filename_len);    memcpy((unsigned char *)(buf+1), filename, filename_len);

Removed from v.1.1  
changed lines
  Added in v.1.1.1.2


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