Diff for /embedaddon/dnsmasq/src/helper.c between versions 1.1.1.1 and 1.1.1.4

version 1.1.1.1, 2013/07/29 19:37:40 version 1.1.1.4, 2021/03/17 00:56:46
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2013 Simon Kelley/* dnsmasq is Copyright (c) 2000-2021 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 18 Line 18
   
 #ifdef HAVE_SCRIPT  #ifdef HAVE_SCRIPT
   
/* This file has code to fork a helper process which recieves data via a pipe /* This file has code to fork a helper process which receives data via a pipe 
    shared with the main process and which is responsible for calling a script when     shared with the main process and which is responsible for calling a script when
    DHCP leases change.     DHCP leases change.
   
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
     struct in6_addr addr6;
   #ifdef HAVE_DHCP6
     int vendorclass_count;
     unsigned int iaid;
   #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 74  int create_helper(int event_fd, int err_fd, uid_t uid, Line 81  int create_helper(int event_fd, int err_fd, uid_t uid,
   pid_t pid;    pid_t pid;
   int i, pipefd[2];    int i, pipefd[2];
   struct sigaction sigact;    struct sigaction sigact;
  unsigned char *alloc_buff = NULL;
   
   /* create the pipe through which the main program sends us commands,    /* create the pipe through which the main program sends us commands,
      then fork our process. */       then fork our process. */
   if (pipe(pipefd) == -1 || !fix_fd(pipefd[1]) || (pid = fork()) == -1)    if (pipe(pipefd) == -1 || !fix_fd(pipefd[1]) || (pid = fork()) == -1)
Line 89  int create_helper(int event_fd, int err_fd, uid_t uid, Line 97  int create_helper(int event_fd, int err_fd, uid_t uid,
       return pipefd[1];        return pipefd[1];
     }      }
   
  /* ignore SIGTERM, so that we can clean up when the main process gets hit  /* ignore SIGTERM and SIGINT, so that we can clean up when the main process gets hit
      and SIGALRM so that we can use sleep() */       and SIGALRM so that we can use sleep() */
   sigact.sa_handler = SIG_IGN;    sigact.sa_handler = SIG_IGN;
   sigact.sa_flags = 0;    sigact.sa_flags = 0;
   sigemptyset(&sigact.sa_mask);    sigemptyset(&sigact.sa_mask);
   sigaction(SIGTERM, &sigact, NULL);    sigaction(SIGTERM, &sigact, NULL);
   sigaction(SIGALRM, &sigact, NULL);    sigaction(SIGALRM, &sigact, NULL);
     sigaction(SIGINT, &sigact, NULL);
   
   if (!option_bool(OPT_DEBUG) && uid != 0)    if (!option_bool(OPT_DEBUG) && uid != 0)
     {      {
Line 122  int create_helper(int event_fd, int err_fd, uid_t uid, Line 131  int create_helper(int event_fd, int err_fd, uid_t uid,
      Don't close err_fd, in case the lua-init fails.       Don't close err_fd, in case the lua-init fails.
      Note that we have to do this before lua init       Note that we have to do this before lua init
      so we don't close any lua fds. */       so we don't close any lua fds. */
  for (max_fd--; max_fd >= 0; max_fd--)  close_fds(max_fd, pipefd[0], event_fd, err_fd);
    if (max_fd != STDOUT_FILENO && max_fd != STDERR_FILENO &&  
        max_fd != STDIN_FILENO && max_fd != pipefd[0] &&  
        max_fd != event_fd && max_fd != err_fd) 
      close(max_fd); 
       
 #ifdef HAVE_LUASCRIPT  #ifdef HAVE_LUASCRIPT
   if (daemon->luascript)    if (daemon->luascript)
Line 179  int create_helper(int event_fd, int err_fd, uid_t uid, Line 184  int create_helper(int event_fd, int err_fd, uid_t uid,
       struct script_data data;        struct script_data data;
       char *p, *action_str, *hostname = NULL, *domain = NULL;        char *p, *action_str, *hostname = NULL, *domain = NULL;
       unsigned char *buf = (unsigned char *)daemon->namebuff;        unsigned char *buf = (unsigned char *)daemon->namebuff;
      unsigned char *end, *extradata, *alloc_buff = NULL;      unsigned char *end, *extradata;
       int is6, err = 0;        int is6, err = 0;
         int pipeout[2];
   
      free(alloc_buff);      /* Free rarely-allocated memory from previous iteration. */
       if (alloc_buff)
         {
           free(alloc_buff);
           alloc_buff = NULL;
         }
               
       /* we read zero bytes when pipe closed: this is our signal to exit */         /* we read zero bytes when pipe closed: this is our signal to exit */ 
       if (!read_write(pipefd[0], (unsigned char *)&data, sizeof(data), 1))        if (!read_write(pipefd[0], (unsigned char *)&data, sizeof(data), 1))
Line 211  int create_helper(int event_fd, int err_fd, uid_t uid, Line 222  int create_helper(int event_fd, int err_fd, uid_t uid,
           action_str = "tftp";            action_str = "tftp";
           is6 = (data.flags != AF_INET);            is6 = (data.flags != AF_INET);
         }          }
      else      else if (data.action == ACTION_ARP)
         {
           action_str = "arp-add";
           is6 = (data.flags != AF_INET);
         }
        else if (data.action == ACTION_ARP_DEL)
         {
           action_str = "arp-del";
           is6 = (data.flags != AF_INET);
           data.action = ACTION_ARP;
         }
        else 
         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 258  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 291  int create_helper(int event_fd, int err_fd, uid_t uid, Line 303  int create_helper(int event_fd, int err_fd, uid_t uid,
           
       if (!is6)        if (!is6)
         inet_ntop(AF_INET, &data.addr, daemon->addrbuff, ADDRSTRLEN);          inet_ntop(AF_INET, &data.addr, daemon->addrbuff, ADDRSTRLEN);
 #ifdef HAVE_DHCP6  
       else        else
        inet_ntop(AF_INET6, &data.hwaddr, daemon->addrbuff, ADDRSTRLEN);        inet_ntop(AF_INET6, &data.addr6, daemon->addrbuff, ADDRSTRLEN);
#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 328  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 */
                 }                  }
             }              }
             else if (data.action == ACTION_ARP)
               {
                 lua_getglobal(lua, "arp"); 
                 if (lua_type(lua, -1) != LUA_TFUNCTION)
                   lua_pop(lua, 1); /* arp function optional */
                 else
                   {
                     lua_pushstring(lua, action_str); /* arg1 - action */
                     lua_newtable(lua);               /* arg2 - data table */
                     lua_pushstring(lua, daemon->addrbuff);
                     lua_setfield(lua, -2, "client_address");
                     lua_pushstring(lua, daemon->dhcp_buff);
                     lua_setfield(lua, -2, "mac_address");
                     lua_call(lua, 2, 0);  /* pass 2 values, expect 0 */
                   }
               }
           else            else
             {              {
               lua_getglobal(lua, "lease");     /* function to call */                lua_getglobal(lua, "lease");     /* function to call */
Line 329  int create_helper(int event_fd, int err_fd, uid_t uid, Line 357  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 403  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 455  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 441  int create_helper(int event_fd, int err_fd, uid_t uid, Line 473  int create_helper(int event_fd, int err_fd, uid_t uid,
       if (!daemon->lease_change_command)        if (!daemon->lease_change_command)
         continue;          continue;
   
         /* Pipe to capture stdout and stderr from script */
         if (!option_bool(OPT_DEBUG) && pipe(pipeout) == -1)
           continue;
         
       /* possible fork errors are all temporary resource problems */        /* possible fork errors are all temporary resource problems */
       while ((pid = fork()) == -1 && (errno == EAGAIN || errno == ENOMEM))        while ((pid = fork()) == -1 && (errno == EAGAIN || errno == ENOMEM))
         sleep(2);          sleep(2);
   
       if (pid == -1)        if (pid == -1)
        continue;        {
           if (!option_bool(OPT_DEBUG))
             {
               close(pipeout[0]);
               close(pipeout[1]);
             }
           continue;
         }
               
       /* wait for child to complete */        /* wait for child to complete */
       if (pid != 0)        if (pid != 0)
         {          {
             if (!option_bool(OPT_DEBUG))
               {
                 FILE *fp;
             
                 close(pipeout[1]);
                 
                 /* Read lines sent to stdout/err by the script and pass them back to be logged */
                 if (!(fp = fdopen(pipeout[0], "r")))
                   close(pipeout[0]);
                 else
                   {
                     while (fgets(daemon->packet, daemon->packet_buff_sz, fp))
                       {
                         /* do not include new lines, log will append them */
                         size_t len = strlen(daemon->packet);
                         if (len > 0)
                           {
                             --len;
                             if (daemon->packet[len] == '\n')
                               daemon->packet[len] = 0;
                           }
                         send_event(event_fd, EVENT_SCRIPT_LOG, 0, daemon->packet);
                       }
                     fclose(fp);
                   }
               }
             
           /* reap our children's children, if necessary */            /* reap our children's children, if necessary */
           while (1)            while (1)
             {              {
Line 473  int create_helper(int event_fd, int err_fd, uid_t uid, Line 543  int create_helper(int event_fd, int err_fd, uid_t uid,
                       
           continue;            continue;
         }          }
   
         if (!option_bool(OPT_DEBUG))
           {
             /* map stdout/stderr of script to pipeout */
             close(pipeout[0]);
             dup2(pipeout[1], STDOUT_FILENO);
             dup2(pipeout[1], STDERR_FILENO);
             close(pipeout[1]);
           }
               
      if (data.action != ACTION_TFTP)      if (data.action != ACTION_TFTP && data.action != ACTION_ARP)
         {          {
          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 572  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 582  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 529  int create_helper(int event_fd, int err_fd, uid_t uid, Line 604  int create_helper(int event_fd, int err_fd, uid_t uid,
               buf = grab_extradata(buf, end, "DNSMASQ_CIRCUIT_ID", &err);                buf = grab_extradata(buf, end, "DNSMASQ_CIRCUIT_ID", &err);
               buf = grab_extradata(buf, end, "DNSMASQ_SUBSCRIBER_ID", &err);                buf = grab_extradata(buf, end, "DNSMASQ_SUBSCRIBER_ID", &err);
               buf = grab_extradata(buf, end, "DNSMASQ_REMOTE_ID", &err);                buf = grab_extradata(buf, end, "DNSMASQ_REMOTE_ID", &err);
                 buf = grab_extradata(buf, end, "DNSMASQ_REQUESTED_OPTIONS", &err);
             }              }
                       
           buf = grab_extradata(buf, end, "DNSMASQ_TAGS", &err);            buf = grab_extradata(buf, end, "DNSMASQ_TAGS", &err);
   
           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 620  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;          
            }          my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &err);
         }          }
      
      if (option_bool(OPT_LOG_OPTS)) 
        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 569  int create_helper(int event_fd, int err_fd, uid_t uid, Line 639  int create_helper(int event_fd, int err_fd, uid_t uid,
       if (err == 0)        if (err == 0)
         {          {
           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, 
                action_str, daemon->dhcp_buff, daemon->addrbuff, hostname, (char*)NULL);                (is6 && data.action != ACTION_ARP) ? 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 652  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 740  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 760  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 821  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  
   else    else
    memcpy(buf->hwaddr, &peer->in6.sin6_addr, IN6ADDRSZ);    buf->addr6 = peer->in6.sin6_addr;
#endif 
   
   memcpy((unsigned char *)(buf+1), filename, filename_len);    memcpy((unsigned char *)(buf+1), filename, filename_len);
       
   bytes_in_buf = sizeof(struct script_data) +  filename_len;    bytes_in_buf = sizeof(struct script_data) +  filename_len;
 }  }
 #endif  #endif
   
   void queue_arp(int action, unsigned char *mac, int maclen, int family, union all_addr *addr)
   {
     /* no script */
     if (daemon->helperfd == -1)
       return;
     
     buff_alloc(sizeof(struct script_data));
     memset(buf, 0, sizeof(struct script_data));
   
     buf->action = action;
     buf->hwaddr_len = maclen;
     buf->hwaddr_type =  ARPHRD_ETHER; 
     if ((buf->flags = family) == AF_INET)
       buf->addr = addr->addr4;
     else
       buf->addr6 = addr->addr6;
     
     memcpy(buf->hwaddr, mac, maclen);
     
     bytes_in_buf = sizeof(struct script_data);
   }
   
 int helper_buf_empty(void)  int helper_buf_empty(void)
 {  {

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


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