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

version 1.1.1.3, 2016/11/02 09:57:01 version 1.1.1.4, 2021/03/17 00:56:46
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2016 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 64  struct script_data Line 64  struct script_data
 #ifdef HAVE_TFTP  #ifdef HAVE_TFTP
   off_t file_len;    off_t file_len;
 #endif  #endif
 #ifdef HAVE_IPV6  
   struct in6_addr addr6;    struct in6_addr addr6;
 #endif  
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
  int iaid, vendorclass_count;  int vendorclass_count;
   unsigned int iaid;
 #endif  #endif
   unsigned char hwaddr[DHCP_CHADDR_MAX];    unsigned char hwaddr[DHCP_CHADDR_MAX];
   char interface[IF_NAMESIZE];    char interface[IF_NAMESIZE];
Line 82  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 97  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 130  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 187  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 300  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_IPV6  
       else        else
         inet_ntop(AF_INET6, &data.addr6, daemon->addrbuff, ADDRSTRLEN);          inet_ntop(AF_INET6, &data.addr6, daemon->addrbuff, ADDRSTRLEN);
 #endif  
   
 #ifdef HAVE_TFTP  #ifdef HAVE_TFTP
       /* file length */        /* file length */
Line 472  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 504  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 && data.action != ACTION_ARP)        if (data.action != ACTION_TFTP && data.action != ACTION_ARP)
         {          {
Line 556  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);
Line 579  int create_helper(int event_fd, int err_fd, uid_t uid, Line 628  int create_helper(int event_fd, int err_fd, uid_t uid,
             hostname = NULL;              hostname = NULL;
                       
           my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &err);            my_setenv("DNSMASQ_LOG_DHCP", option_bool(OPT_LOG_OPTS) ? "1" : NULL, &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 775  void queue_tftp(off_t file_len, char *filename, union  Line 825  void queue_tftp(off_t file_len, char *filename, union 
   
   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
     buf->addr6 = peer->in6.sin6_addr;      buf->addr6 = peer->in6.sin6_addr;
 #endif  
   
   memcpy((unsigned char *)(buf+1), filename, filename_len);    memcpy((unsigned char *)(buf+1), filename, filename_len);
       
Line 786  void queue_tftp(off_t file_len, char *filename, union  Line 834  void queue_tftp(off_t file_len, char *filename, union 
 }  }
 #endif  #endif
   
void queue_arp(int action, unsigned char *mac, int maclen, int family, struct all_addr *addr)void queue_arp(int action, unsigned char *mac, int maclen, int family, union all_addr *addr)
 {  {
   /* no script */    /* no script */
   if (daemon->helperfd == -1)    if (daemon->helperfd == -1)
Line 799  void queue_arp(int action, unsigned char *mac, int mac Line 847  void queue_arp(int action, unsigned char *mac, int mac
   buf->hwaddr_len = maclen;    buf->hwaddr_len = maclen;
   buf->hwaddr_type =  ARPHRD_ETHER;     buf->hwaddr_type =  ARPHRD_ETHER; 
   if ((buf->flags = family) == AF_INET)    if ((buf->flags = family) == AF_INET)
    buf->addr = addr->addr.addr4;    buf->addr = addr->addr4;
#ifdef HAVE_IPV6 
   else    else
    buf->addr6 = addr->addr.addr6;    buf->addr6 = addr->addr6;
#endif 
       
   memcpy(buf->hwaddr, mac, maclen);    memcpy(buf->hwaddr, mac, maclen);
       

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


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