[BACK]Return to dhclient.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / mpl / dhcp / dist / client

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/external/mpl/dhcp/dist/client/dhclient.c between version 1.4 and 1.5

version 1.4, 2021/05/26 22:52:31 version 1.5, 2022/04/03 01:10:57
Line 5 
Line 5 
    DHCP Client. */     DHCP Client. */
   
 /*  /*
  * Copyright (c) 2004-2021 by Internet Systems Consortium, Inc. ("ISC")   * Copyright (c) 2004-2022 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 1995-2003 by Internet Software Consortium   * Copyright (c) 1995-2003 by Internet Software Consortium
  *   *
  * This Source Code Form is subject to the terms of the Mozilla Public   * This Source Code Form is subject to the terms of the Mozilla Public
Line 21 
Line 21 
  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.   * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *   *
  *   Internet Systems Consortium, Inc.   *   Internet Systems Consortium, Inc.
  *   950 Charter Street   *   PO Box 360
  *   Redwood City, CA 94063   *   Newmarket, NH 03857 USA
  *   <info@isc.org>   *   <info@isc.org>
  *   https://www.isc.org/   *   https://www.isc.org/
  *   *
Line 84  int decline_wait_time = 10; /* Default t
Line 84  int decline_wait_time = 10; /* Default t
 #define ASSERT_STATE(state_is, state_shouldbe) {}  #define ASSERT_STATE(state_is, state_shouldbe) {}
   
 #ifndef UNIT_TEST  #ifndef UNIT_TEST
 static const char copyright[] = "Copyright 2004-2021 Internet Systems Consortium.";  static const char copyright[] = "Copyright 2004-2022 Internet Systems Consortium.";
 static const char arr [] = "All rights reserved.";  static const char arr [] = "All rights reserved.";
 static const char message [] = "Internet Systems Consortium DHCP Client";  static const char message [] = "Internet Systems Consortium DHCP Client";
 static const char url [] = "For info, please visit https://www.isc.org/software/dhcp/";  static const char url [] = "For info, please visit https://www.isc.org/software/dhcp/";
 #endif /* UNIT_TEST */  #endif /* UNIT_TEST */
   
 u_int16_t local_port = 0;  extern u_int16_t local_port;
 u_int16_t remote_port = 0;  extern u_int16_t remote_port;
   
 #if defined(DHCPv6) && defined(DHCP4o6)  #if defined(DHCPv6) && defined(DHCP4o6)
 int dhcp4o6_state = -1; /* -1 = stopped, 0 = polling, 1 = started */  int dhcp4o6_state = -1; /* -1 = stopped, 0 = polling, 1 = started */
 #endif  #endif
Line 232  add_interfaces(char **ifaces, int niface
Line 233  add_interfaces(char **ifaces, int niface
  * the description of the command line.  The arguments provide   * the description of the command line.  The arguments provide
  * a way for the caller to request more specific information about   * a way for the caller to request more specific information about
  * the error be printed as well.  Mostly this will be that some   * the error be printed as well.  Mostly this will be that some
  * comamnd doesn't include its argument.   * command doesn't include its argument.
  *   *
  * \param sfmt - The basic string and format for the specific error   * \param sfmt - The basic string and format for the specific error
  * \param sarg - Generally the offending argument from the comamnd line.   * \param sarg - Generally the offending argument from the command line.
  *   *
  * \return Nothing   * \return Nothing
  */   */
Line 634  main(int argc, char **argv) {
Line 635  main(int argc, char **argv) {
                 } else if (argv[i][0] == '-') {                  } else if (argv[i][0] == '-') {
                         usage("Unknown command: %s", argv[i]);                          usage("Unknown command: %s", argv[i]);
                 } else if (interfaces_requested < 0) {                  } else if (interfaces_requested < 0) {
                         usage("No interfaces comamnd -n and "                          usage("No interfaces command -n and "
                               " requested interface %s", argv[i]);                                " requested interface %s", argv[i]);
                 } else {                  } else {
                     ifaces[interfaces_requested++] = argv[i];                      ifaces[interfaces_requested++] = argv[i];
Line 890  main(int argc, char **argv) {
Line 891  main(int argc, char **argv) {
                             ? DISCOVER_REQUESTED                              ? DISCOVER_REQUESTED
                             : DISCOVER_RUNNING);                              : DISCOVER_RUNNING);
   
         /* Make up a seed for the random number generator from current          /* PLEASE PREFER the random device: not all systems use random
            time plus the sum of the last four bytes of each           * process identifiers so the alternative can be predictable. */
            interface's hardware address interpreted as an integer.  
            Not much entropy, but we're booting, so we're not likely to  
            find anything better. */  
         seed = 0;          seed = 0;
         for (ip = interfaces; ip; ip = ip->next) {          size_t nrnd = 0;
                 int junk;  #ifdef ISC_PATH_RANDOMDEV
                 memcpy(&junk,          FILE *frnd = fopen(ISC_PATH_RANDOMDEV, "r");
                        &ip->hw_address.hbuf[ip->hw_address.hlen -          if (frnd) {
                                             sizeof seed], sizeof seed);                  nrnd = fread(&seed, sizeof(seed), 1, frnd);
                 seed += junk;                  fclose(frnd);
         }          }
         srandom(seed + cur_time + (unsigned)getpid());  #endif
           /* Please leave the compiler to emit a warning about a constant
            * condition in the if test. */
           if (!nrnd) {
                   /* Make up a seed for the random number generator from current
                      time plus the sum of the last four bytes of each
                      interface's hardware address interpreted as an integer.
                      Not much entropy, but we're booting, so we're not likely to
                      find anything better. */
   
                   for (ip = interfaces; ip; ip = ip->next) {
                           int junk;
                           memcpy(&junk,
                                  &ip->hw_address.hbuf[ip->hw_address.hlen -
                                                       sizeof seed], sizeof seed);
                           seed += junk;
                   }
                   seed += cur_time + (unsigned)getpid();
           }
           srandom(seed);
   
         /*          /*
          * Establish a default DUID.  We always do so for v6 and           * Establish a default DUID.  We always do so for v6 and
Line 1306  void state_init (cpp)
Line 1322  void state_init (cpp)
         send_discover (client);          send_discover (client);
 }  }
   
   /* check_v6only is called by dhcpoffer and dhcpack. It checks if a
    * requested v6-only-preferred option is present and returned the
    * V6ONLY_WAIT delay to suspend DHCPv4. */
   
   uint32_t check_v6only(packet, client)
           struct packet *packet;
           struct client_state *client;
   {
           int i;
           struct option **req;
           isc_boolean_t found = ISC_FALSE;
           struct option_cache *oc;
           struct data_string data;
           uint32_t v6only_wait = 0;
   
           /* Check if the v6-only-preferred was requested. */
           req = client->config->requested_options;
   
           if (req == NULL)
                   return 0;
   
           for (i = 0 ; req[i] != NULL ; i++) {
                   if ((req[i]->universe == &dhcp_universe) &&
                       (req[i]->code == DHO_V6_ONLY_PREFERRED)) {
                           found = ISC_TRUE;
                           break;
                   }
           }
   
           if (found == ISC_FALSE)
                   return 0;
   
           /* Get the V6ONLY_WAIT timer. */
           oc = lookup_option(&dhcp_universe, packet->options,
                              DHO_V6_ONLY_PREFERRED);
           if (!oc)
                   return 0;
   
           memset(&data, 0, sizeof(data));
   
           if (evaluate_option_cache(&data, packet, (struct lease *)0, client,
                                     packet->options, (struct option_state *)0,
                                     &global_scope, oc, MDL)) {
                   if (data.len == 4) {
                           v6only_wait = getULong(data.data);
                           if (v6only_wait < MIN_V6ONLY_WAIT)
                                   v6only_wait = MIN_V6ONLY_WAIT;
                   }
                   data_string_forget(&data, MDL);
           }
   
           return (v6only_wait);
   }
   
   /* finish_v6only is called when the V6ONLY_WAIT timer expired. */
   
   void finish_v6only(cpp)
           void *cpp;
   {
           struct client_state *client = cpp;
   
           cancel_timeout(finish_v6only, client);
           client->state = S_INIT;
           state_init(cpp);
   }
   
   /*
    * start_v6only is called when a requested v6-only-preferred option was
    * returned by the server. */
   
   void start_v6only(client, v6only_wait)
           struct client_state *client;
           uint32_t v6only_wait;
   {
           struct timeval tv;
   
           /* Enter V6ONLY state. */
   
           client->state = S_V6ONLY;
   
           /* Run the client script. */
           script_init(client, "V6ONLY", NULL);
           if (client->active) {
                   script_write_params(client, "old_", client->active);
                   destroy_client_lease(client->active);
                   client->active = NULL;
           }
           script_write_requested(client);
           client_envadd(client, "", "v6-only-preferred", "%lu",
                         (long unsigned)v6only_wait);
           script_go(client);
   
           /* Trigger finish_v6only after V6ONLY_WAIT seconds. */
           tv.tv_sec = cur_tv.tv_sec + v6only_wait;
           tv.tv_usec = cur_tv.tv_usec;
   
           add_timeout(&tv, finish_v6only, client, 0, 0);
   }
   
 /*  /*
  * state_selecting is called when one or more DHCPOFFER packets have been   * state_selecting is called when one or more DHCPOFFER packets have been
  * received and a configurable period of time has passed.   * received and a configurable period of time has passed.
Line 1421  void dhcpack (packet)
Line 1536  void dhcpack (packet)
 {  {
         struct interface_info *ip = packet -> interface;          struct interface_info *ip = packet -> interface;
         struct client_state *client;          struct client_state *client;
           uint32_t v6only_wait;
         struct client_lease *lease;          struct client_lease *lease;
         struct option_cache *oc;          struct option_cache *oc;
         struct data_string ds;          struct data_string ds;
Line 1448  void dhcpack (packet)
Line 1564  void dhcpack (packet)
                   inet_ntoa(packet->raw->yiaddr),                    inet_ntoa(packet->raw->yiaddr),
                   piaddr (packet->client_addr));                    piaddr (packet->client_addr));
   
           /* Check v6only first. */
           v6only_wait = check_v6only(packet, client);
           if (v6only_wait > 0) {
                   log_info("v6 only preferred for %lu seconds.",
                            (long unsigned)v6only_wait);
                   cancel_timeout(send_request, client);
                   start_v6only(client, v6only_wait);
                   return;
           }
   
         lease = packet_to_lease (packet, client);          lease = packet_to_lease (packet, client);
         if (!lease) {          if (!lease) {
                 log_info ("packet_to_lease failed.");                  log_info ("packet_to_lease failed.");
Line 1601  void bind_lease (client)
Line 1727  void bind_lease (client)
                 script_write_params(client, "alias_", client->alias);                  script_write_params(client, "alias_", client->alias);
   
         /* If the BOUND/RENEW code detects another machine using the          /* If the BOUND/RENEW code detects another machine using the
            offered address, it exits nonzero.  We need to send a             offered address, then per our man page it should exit with
            DHCPDECLINE and toss the lease. */         a non-zero status, to which we send a DHCPDECLINE and toss
         if (script_go(client)) {         the lease. A return value of less than zero indicates
          the script crashed (e.g. segfault) which script_go will log
          but we will ignore here. */
           if (script_go(client) > 0)  {
                 make_decline(client, client->new);                  make_decline(client, client->new);
                 send_decline(client);                  send_decline(client);
                 destroy_client_lease(client->new);                  destroy_client_lease(client->new);
Line 1726  void state_stop (cpp)
Line 1855  void state_stop (cpp)
         cancel_timeout(send_discover, client);          cancel_timeout(send_discover, client);
         cancel_timeout(send_request, client);          cancel_timeout(send_request, client);
         cancel_timeout(state_bound, client);          cancel_timeout(state_bound, client);
           cancel_timeout(finish_v6only, client);
   
         /* If we have an address, unconfigure it. */          /* If we have an address, unconfigure it. */
         if (client->active) {          if (client->active) {
Line 2085  void dhcpoffer (packet)
Line 2215  void dhcpoffer (packet)
 {  {
         struct interface_info *ip = packet -> interface;          struct interface_info *ip = packet -> interface;
         struct client_state *client;          struct client_state *client;
           uint32_t v6only_wait;
         struct client_lease *lease, *lp;          struct client_lease *lease, *lp;
         struct option **req;          struct option **req;
         int i;          int i;
Line 2112  void dhcpoffer (packet)
Line 2243  void dhcpoffer (packet)
                  inet_ntoa(packet->raw->yiaddr),                   inet_ntoa(packet->raw->yiaddr),
                  piaddr(packet->client_addr));                   piaddr(packet->client_addr));
   
           /* Check v6only first. */
           v6only_wait = check_v6only(packet, client);
           if (v6only_wait > 0) {
                   log_info("%s: v6 only preferred for %lu.", obuf,
                            (long unsigned)v6only_wait);
                   cancel_timeout(send_discover, client);
                   start_v6only(client, v6only_wait);
                   return;
           }
   
         /* If this lease doesn't supply the minimum required DHCPv4 parameters,          /* If this lease doesn't supply the minimum required DHCPv4 parameters,
          * ignore it.           * ignore it.
          */           */
Line 3321  make_client_options(struct client_state 
Line 3462  make_client_options(struct client_state 
                         hw_idx = 0;                          hw_idx = 0;
                         hw_len = client->interface->hw_address.hlen;                          hw_len = client->interface->hw_address.hlen;
                 }                  }
                 memcpy(&client_identifier.buffer->data + 5 - hw_len,                  memcpy(client_identifier.buffer->data + 5 - hw_len,
                        client->interface->hw_address.hbuf + hw_idx,                         client->interface->hw_address.hbuf + hw_idx,
                        hw_len);                         hw_len);
   
                 /* Add the default duid */                  /* Add the default duid */
                 memcpy(&client_identifier.buffer->data+(1+4),                  memcpy(client_identifier.buffer->data + (1 + 4),
                        default_duid.data, default_duid.len);                         default_duid.data, default_duid.len);
   
                 /* And save the option */                  /* And save the option */
Line 4497  int script_go(struct client_state *clien
Line 4638  int script_go(struct client_state *clien
         }          }
         dfree (envp, MDL);          dfree (envp, MDL);
         gettimeofday(&cur_tv, NULL);          gettimeofday(&cur_tv, NULL);
         return (WIFEXITED (wstatus) ?  
                 WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));      if (!WIFEXITED(wstatus)) {
           int sigval = WTERMSIG(wstatus);
           log_error ("script_go script: %s was terminated by signal %d", scriptName, sigval);
           return  (-sigval);
       }
   
       return (WEXITSTATUS(wstatus));
 }  }
   
 void client_envadd (struct client_state *client,  void client_envadd (struct client_state *client,
Line 4685  void client_location_changed ()
Line 4832  void client_location_changed ()
                               case S_REBINDING:                                case S_REBINDING:
                               case S_STOPPED:                                case S_STOPPED:
                               case S_DECLINING:                                case S_DECLINING:
                                 case S_V6ONLY:
                                 break;                                  break;
                         }                          }
                         client -> state = S_INIT;                          client -> state = S_INIT;
Line 4763  void do_release(client)
Line 4911  void do_release(client)
         cancel_timeout (state_init, client);          cancel_timeout (state_init, client);
         cancel_timeout (send_request, client);          cancel_timeout (send_request, client);
         cancel_timeout (state_reboot, client);          cancel_timeout (state_reboot, client);
           cancel_timeout (finish_v6only, client);
         client -> state = S_STOPPED;          client -> state = S_STOPPED;
   
 #if defined(DHCPv6) && defined(DHCP4o6)  #if defined(DHCPv6) && defined(DHCP4o6)

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

CVSweb <webmaster@jp.NetBSD.org>