[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.1.1.3 and 1.1.1.4

version 1.1.1.3, 2021/05/26 22:48:47 version 1.1.1.4, 2022/04/03 01:08:44
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 82  int decline_wait_time = 10; /* Default t
Line 82  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 141  static void dhclient_ddns_cb_free(dhcp_d
Line 142  static void dhclient_ddns_cb_free(dhcp_d
  * 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 574  main(int argc, char **argv) {
Line 575  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 {
                     struct interface_info *tmp = NULL;                      struct interface_info *tmp = NULL;
Line 836  main(int argc, char **argv) {
Line 837  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 1249  void state_init (cpp)
Line 1265  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 1344  void dhcpack (packet)
Line 1459  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 1379  void dhcpack (packet)
Line 1495  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 1532  void bind_lease (client)
Line 1658  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 1657  void state_stop (cpp)
Line 1786  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 2016  void dhcpoffer (packet)
Line 2146  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 2051  void dhcpoffer (packet)
Line 2182  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 3266  make_client_options(struct client_state 
Line 3407  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 4442  int script_go(struct client_state *clien
Line 4583  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 4630  void client_location_changed ()
Line 4777  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 4708  void do_release(client)
Line 4856  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.1.1.3  
changed lines
  Added in v.1.1.1.4

CVSweb <webmaster@jp.NetBSD.org>