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


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.

  25  */
  26 
  27 #include <stdio.h>
  28 #include <stdlib.h>
  29 #include <string.h>
  30 #include <errno.h>
  31 #include <fcntl.h>
  32 #include <unistd.h>
  33 #include <stropts.h>
  34 #include <sys/sockio.h>
  35 #include <sys/types.h>
  36 #include <sys/stat.h>
  37 #include <sys/socket.h>
  38 #include <net/route.h>
  39 #include <netinet/in.h>
  40 #include <inet/ip.h>
  41 #include <arpa/inet.h>
  42 #include <libintl.h>
  43 #include <libdlpi.h>
  44 #include <libinetutil.h>


 711                 if (nvpair_value_nvlist(nvp, &nvl) != 0)
 712                         continue;
 713 
 714                 if (nvlist_lookup_string(nvl, IPADM_NVP_FAMILY, &afstr) == 0) {
 715                         status = i_ipadm_plumb_if(iph, newifname, atoi(afstr),
 716                             IPADM_OPT_ACTIVE);
 717                         /*
 718                          * If the interface is already plumbed, we should
 719                          * ignore this error because there might be address
 720                          * address objects on that interface that needs to
 721                          * be enabled again.
 722                          */
 723                         if (status == IPADM_IF_EXISTS)
 724                                 status = IPADM_SUCCESS;
 725 
 726                         if (is_ngz)
 727                                 af = atoi(afstr);
 728                 } else if (nvlist_lookup_string(nvl, IPADM_NVP_AOBJNAME,
 729                     &aobjstr) == 0) {
 730                         /*
 731                          * For a static address, we need to search for
 732                          * the prefixlen in the nvlist `ifnvl'.
 733                          */
 734                         if (nvlist_exists(nvl, IPADM_NVP_IPV4ADDR) ||
 735                             nvlist_exists(nvl, IPADM_NVP_IPV6ADDR)) {
 736                                 status = i_ipadm_merge_prefixlen_from_nvl(ifnvl,

 737                                     nvl, aobjstr);
 738                                 if (status != IPADM_SUCCESS)
 739                                         continue;
 740                         }
 741                         status = i_ipadm_init_addrobj(iph, nvl);
 742                         /*
 743                          * If this address is in use on some other interface,
 744                          * we want to record an error to be returned as
 745                          * a soft error and continue processing the rest of
 746                          * the addresses.
 747                          */
 748                         if (status == IPADM_ADDR_NOTAVAIL) {
 749                                 ret_status = IPADM_ALL_ADDRS_NOT_ENABLED;
 750                                 status = IPADM_SUCCESS;
 751                         }
 752                 } else {
 753                         assert(nvlist_exists(nvl, IPADM_NVP_PROTONAME));
 754                         status = i_ipadm_init_ifprop(iph, nvl);
 755                 }
 756                 if (status != IPADM_SUCCESS)


 938                  * to new buffer.
 939                  */
 940                 if (err == 0) {
 941                         void *newp;
 942 
 943                         /* allocated memory will be freed by the caller */
 944                         if ((newp = realloc(*rbufp, darg.rsize)) == NULL) {
 945                                 err = ENOMEM;
 946                         } else {
 947                                 *rbufp = newp;
 948                                 (void) memcpy(*rbufp, darg.rbuf, darg.rsize);
 949                         }
 950                 }
 951                 /* munmap() the door buffer */
 952                 (void) munmap(darg.rbuf, darg.rsize);
 953         } else {
 954                 if (darg.rsize != rsize)
 955                         err = EBADE;
 956         }
 957         return (err);













































































 958 }


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  25  * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
  26  */
  27 
  28 #include <stdio.h>
  29 #include <stdlib.h>
  30 #include <string.h>
  31 #include <errno.h>
  32 #include <fcntl.h>
  33 #include <unistd.h>
  34 #include <stropts.h>
  35 #include <sys/sockio.h>
  36 #include <sys/types.h>
  37 #include <sys/stat.h>
  38 #include <sys/socket.h>
  39 #include <net/route.h>
  40 #include <netinet/in.h>
  41 #include <inet/ip.h>
  42 #include <arpa/inet.h>
  43 #include <libintl.h>
  44 #include <libdlpi.h>
  45 #include <libinetutil.h>


 712                 if (nvpair_value_nvlist(nvp, &nvl) != 0)
 713                         continue;
 714 
 715                 if (nvlist_lookup_string(nvl, IPADM_NVP_FAMILY, &afstr) == 0) {
 716                         status = i_ipadm_plumb_if(iph, newifname, atoi(afstr),
 717                             IPADM_OPT_ACTIVE);
 718                         /*
 719                          * If the interface is already plumbed, we should
 720                          * ignore this error because there might be address
 721                          * address objects on that interface that needs to
 722                          * be enabled again.
 723                          */
 724                         if (status == IPADM_IF_EXISTS)
 725                                 status = IPADM_SUCCESS;
 726 
 727                         if (is_ngz)
 728                                 af = atoi(afstr);
 729                 } else if (nvlist_lookup_string(nvl, IPADM_NVP_AOBJNAME,
 730                     &aobjstr) == 0) {
 731                         /*
 732                          * For addresses, we need to relocate addrprops from the
 733                          * nvlist `ifnvl'.
 734                          */
 735                         if (nvlist_exists(nvl, IPADM_NVP_IPV4ADDR) ||
 736                             nvlist_exists(nvl, IPADM_NVP_IPV6ADDR) ||
 737                             nvlist_exists(nvl, IPADM_NVP_DHCP)) {
 738                                 status = i_ipadm_merge_addrprops_from_nvl(ifnvl,
 739                                     nvl, aobjstr);
 740                                 if (status != IPADM_SUCCESS)
 741                                         continue;
 742                         }
 743                         status = i_ipadm_init_addrobj(iph, nvl);
 744                         /*
 745                          * If this address is in use on some other interface,
 746                          * we want to record an error to be returned as
 747                          * a soft error and continue processing the rest of
 748                          * the addresses.
 749                          */
 750                         if (status == IPADM_ADDR_NOTAVAIL) {
 751                                 ret_status = IPADM_ALL_ADDRS_NOT_ENABLED;
 752                                 status = IPADM_SUCCESS;
 753                         }
 754                 } else {
 755                         assert(nvlist_exists(nvl, IPADM_NVP_PROTONAME));
 756                         status = i_ipadm_init_ifprop(iph, nvl);
 757                 }
 758                 if (status != IPADM_SUCCESS)


 940                  * to new buffer.
 941                  */
 942                 if (err == 0) {
 943                         void *newp;
 944 
 945                         /* allocated memory will be freed by the caller */
 946                         if ((newp = realloc(*rbufp, darg.rsize)) == NULL) {
 947                                 err = ENOMEM;
 948                         } else {
 949                                 *rbufp = newp;
 950                                 (void) memcpy(*rbufp, darg.rbuf, darg.rsize);
 951                         }
 952                 }
 953                 /* munmap() the door buffer */
 954                 (void) munmap(darg.rbuf, darg.rsize);
 955         } else {
 956                 if (darg.rsize != rsize)
 957                         err = EBADE;
 958         }
 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;
1037 }