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 }
|