Print this page
7388 Support DHCP Client FQDN. Allow IAID/DUID for all v4.

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libipadm/common/libipadm.c
          +++ new/usr/src/lib/libipadm/common/libipadm.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
       25 + * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
  25   26   */
  26   27  
  27   28  #include <stdio.h>
  28   29  #include <stdlib.h>
  29   30  #include <string.h>
  30   31  #include <errno.h>
  31   32  #include <fcntl.h>
  32   33  #include <unistd.h>
  33   34  #include <stropts.h>
  34   35  #include <sys/sockio.h>
↓ open down ↓ 686 lines elided ↑ open up ↑
 721  722                           * be enabled again.
 722  723                           */
 723  724                          if (status == IPADM_IF_EXISTS)
 724  725                                  status = IPADM_SUCCESS;
 725  726  
 726  727                          if (is_ngz)
 727  728                                  af = atoi(afstr);
 728  729                  } else if (nvlist_lookup_string(nvl, IPADM_NVP_AOBJNAME,
 729  730                      &aobjstr) == 0) {
 730  731                          /*
 731      -                         * For a static address, we need to search for
 732      -                         * the prefixlen in the nvlist `ifnvl'.
      732 +                         * For addresses, we need to relocate addrprops from the
      733 +                         * nvlist `ifnvl'.
 733  734                           */
 734  735                          if (nvlist_exists(nvl, IPADM_NVP_IPV4ADDR) ||
 735      -                            nvlist_exists(nvl, IPADM_NVP_IPV6ADDR)) {
 736      -                                status = i_ipadm_merge_prefixlen_from_nvl(ifnvl,
      736 +                            nvlist_exists(nvl, IPADM_NVP_IPV6ADDR) ||
      737 +                            nvlist_exists(nvl, IPADM_NVP_DHCP)) {
      738 +                                status = i_ipadm_merge_addrprops_from_nvl(ifnvl,
 737  739                                      nvl, aobjstr);
 738  740                                  if (status != IPADM_SUCCESS)
 739  741                                          continue;
 740  742                          }
 741  743                          status = i_ipadm_init_addrobj(iph, nvl);
 742  744                          /*
 743  745                           * If this address is in use on some other interface,
 744  746                           * we want to record an error to be returned as
 745  747                           * a soft error and continue processing the rest of
 746  748                           * the addresses.
↓ open down ↓ 201 lines elided ↑ open up ↑
 948  950                                  (void) memcpy(*rbufp, darg.rbuf, darg.rsize);
 949  951                          }
 950  952                  }
 951  953                  /* munmap() the door buffer */
 952  954                  (void) munmap(darg.rbuf, darg.rsize);
 953  955          } else {
 954  956                  if (darg.rsize != rsize)
 955  957                          err = EBADE;
 956  958          }
 957  959          return (err);
      960 +}
      961 +
      962 +/*
      963 + * ipadm_is_nil_hostname() : Determine if the `hostname' is nil: i.e.,
      964 + *                      NULL, empty, or a single space (e.g., as returned by
      965 + *                      domainname(1M)/sysinfo).
      966 + *
      967 + *   input: const char *: the hostname to inspect;
      968 + *  output: boolean_t: B_TRUE if `hostname' is not NULL satisfies the
      969 + *                      criteria above; otherwise, B_FALSE;
      970 + */
      971 +
      972 +boolean_t
      973 +ipadm_is_nil_hostname(const char *hostname)
      974 +{
      975 +        return (hostname == NULL || *hostname == '\0'
      976 +            || (*hostname == ' ' && hostname[1] == '\0'));
      977 +}
      978 +
      979 +/*
      980 + * ipadm_is_valid_hostname(): check whether a string is a valid hostname
      981 + *
      982 + *   input: const char *: the string to verify as a hostname
      983 + *  output: boolean_t: B_TRUE if the string is a valid hostname
      984 + *
      985 + * Note that we accept host names beginning with a digit, which is not
      986 + * strictly legal according to the RFCs but is in common practice, so we
      987 + * endeavour to not break what customers are using.
      988 + *
      989 + * RFC 1035 limits a wire-format domain name to 255 octets. For a printable
      990 + * `hostname' as we have, the limit is therefore 253 characters (excluding
      991 + * the terminating '\0'--or 254 characters if the last character of
      992 + * `hostname' is a '.'.
      993 + *
      994 + * Excerpt from section 2.3.1., Preferred name syntax:
      995 + *
      996 + * <domain> ::= <subdomain> | " "
      997 + * <subdomain> ::= <label> | <subdomain> "." <label>
      998 + * <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
      999 + * <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
     1000 + * <let-dig-hyp> ::= <let-dig> | "-"
     1001 + * <let-dig> ::= <letter> | <digit>
     1002 + */
     1003 +boolean_t
     1004 +ipadm_is_valid_hostname(const char *hostname)
     1005 +{
     1006 +        const size_t MAX_READABLE_NAME_LEN = 253;
     1007 +        char last_char;
     1008 +        size_t has_last_dot, namelen, i;
     1009 +
     1010 +        if (hostname == NULL)
     1011 +                return B_FALSE;
     1012 +
     1013 +        namelen = strlen(hostname);
     1014 +        if (namelen < 1)
     1015 +                return B_FALSE;
     1016 +
     1017 +        last_char = hostname[namelen - 1];
     1018 +        has_last_dot = last_char == '.';
     1019 +
     1020 +        if (namelen > MAX_READABLE_NAME_LEN + has_last_dot
     1021 +            || last_char == '-')
     1022 +                return B_FALSE;
     1023 +
     1024 +        for (i = 0; hostname[i] != '\0'; i++) {
     1025 +                /*
     1026 +                 * As noted above, this deviates from RFC 1035 in that it allows a
     1027 +                 * leading digit.
     1028 +                 */
     1029 +                if (isalpha(hostname[i]) || isdigit(hostname[i]) ||
     1030 +                    (((hostname[i] == '-') || (hostname[i] == '.')) && (i > 0)))
     1031 +                        continue;
     1032 +
     1033 +                return (B_FALSE);
     1034 +        }
     1035 +
     1036 +        return B_TRUE;
 958 1037  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX