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

*** 20,29 **** --- 20,30 ---- */ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2016, Chris Fraire <cfraire@me.com>. */ #include <stdio.h> #include <stdlib.h> #include <string.h>
*** 726,741 **** if (is_ngz) af = atoi(afstr); } else if (nvlist_lookup_string(nvl, IPADM_NVP_AOBJNAME, &aobjstr) == 0) { /* ! * For a static address, we need to search for ! * the prefixlen in the nvlist `ifnvl'. */ if (nvlist_exists(nvl, IPADM_NVP_IPV4ADDR) || ! nvlist_exists(nvl, IPADM_NVP_IPV6ADDR)) { ! status = i_ipadm_merge_prefixlen_from_nvl(ifnvl, nvl, aobjstr); if (status != IPADM_SUCCESS) continue; } status = i_ipadm_init_addrobj(iph, nvl); --- 727,743 ---- if (is_ngz) af = atoi(afstr); } else if (nvlist_lookup_string(nvl, IPADM_NVP_AOBJNAME, &aobjstr) == 0) { /* ! * For addresses, we need to relocate addrprops from the ! * nvlist `ifnvl'. */ if (nvlist_exists(nvl, IPADM_NVP_IPV4ADDR) || ! nvlist_exists(nvl, IPADM_NVP_IPV6ADDR) || ! nvlist_exists(nvl, IPADM_NVP_DHCP)) { ! status = i_ipadm_merge_addrprops_from_nvl(ifnvl, nvl, aobjstr); if (status != IPADM_SUCCESS) continue; } status = i_ipadm_init_addrobj(iph, nvl);
*** 953,958 **** --- 955,1037 ---- } else { if (darg.rsize != rsize) err = EBADE; } return (err); + } + + /* + * ipadm_is_nil_hostname() : Determine if the `hostname' is nil: i.e., + * NULL, empty, or a single space (e.g., as returned by + * domainname(1M)/sysinfo). + * + * input: const char *: the hostname to inspect; + * output: boolean_t: B_TRUE if `hostname' is not NULL satisfies the + * criteria above; otherwise, B_FALSE; + */ + + boolean_t + ipadm_is_nil_hostname(const char *hostname) + { + return (hostname == NULL || *hostname == '\0' + || (*hostname == ' ' && hostname[1] == '\0')); + } + + /* + * ipadm_is_valid_hostname(): check whether a string is a valid hostname + * + * input: const char *: the string to verify as a hostname + * output: boolean_t: B_TRUE if the string is a valid hostname + * + * Note that we accept host names beginning with a digit, which is not + * strictly legal according to the RFCs but is in common practice, so we + * endeavour to not break what customers are using. + * + * RFC 1035 limits a wire-format domain name to 255 octets. For a printable + * `hostname' as we have, the limit is therefore 253 characters (excluding + * the terminating '\0'--or 254 characters if the last character of + * `hostname' is a '.'. + * + * Excerpt from section 2.3.1., Preferred name syntax: + * + * <domain> ::= <subdomain> | " " + * <subdomain> ::= <label> | <subdomain> "." <label> + * <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ] + * <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str> + * <let-dig-hyp> ::= <let-dig> | "-" + * <let-dig> ::= <letter> | <digit> + */ + boolean_t + ipadm_is_valid_hostname(const char *hostname) + { + const size_t MAX_READABLE_NAME_LEN = 253; + char last_char; + size_t has_last_dot, namelen, i; + + if (hostname == NULL) + return B_FALSE; + + namelen = strlen(hostname); + if (namelen < 1) + return B_FALSE; + + last_char = hostname[namelen - 1]; + has_last_dot = last_char == '.'; + + if (namelen > MAX_READABLE_NAME_LEN + has_last_dot + || last_char == '-') + return B_FALSE; + + for (i = 0; hostname[i] != '\0'; i++) { + /* + * As noted above, this deviates from RFC 1035 in that it allows a + * leading digit. + */ + if (isalpha(hostname[i]) || isdigit(hostname[i]) || + (((hostname[i] == '-') || (hostname[i] == '.')) && (i > 0))) + continue; + + return (B_FALSE); + } + + return B_TRUE; }