4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
33 #include <libnvpair.h>
40 const char *df_name
; /* parameter name */
41 const char *df_default
; /* default value */
42 int df_min
; /* min value if type DF_INTEGER */
43 int df_max
; /* max value if type DF_INTEGER */
47 * note: keep in the same order as tunable parameter constants in defaults.h
50 static struct dhcp_default defaults
[] = {
52 { "RELEASE_ON_SIGTERM", "0", 0, 0 },
53 { "IGNORE_FAILED_ARP", "1", 0, -1 },
54 { "OFFER_WAIT", "3", 1, 20 },
55 { "ARP_WAIT", "1000", 0, -1 },
56 { "CLIENT_ID", NULL
, 0, 0 },
57 { "PARAM_REQUEST_LIST", NULL
, 0, 0 },
58 { "REQUEST_HOSTNAME", "1", 0, 0 },
59 { "DEBUG_LEVEL", "0", 0, 3 },
60 { "VERBOSE", "0", 0, 0 },
61 { "VERIFIED_LEASE_ONLY", "0", 0, 0 },
62 { "PARAM_IGNORE_LIST", NULL
, 0, 0 }
66 * df_build_cache(): builds the defaults nvlist cache
69 * output: a pointer to an nvlist of the current defaults, or NULL on failure
77 char *param
, *pastv6
, *value
, *end
;
80 struct dhcp_default
*defp
;
82 if ((fp
= fopen(DHCP_AGENT_DEFAULTS
, "r")) == NULL
)
85 if (nvlist_alloc(&nvlist
, NV_UNIQUE_NAME
, 0) != 0) {
86 dhcpmsg(MSG_WARNING
, "cannot build default value cache; "
87 "using built-in defaults");
92 while (fgets(entry
, sizeof (entry
), fp
) != NULL
) {
93 for (i
= 0; entry
[i
] == ' '; i
++)
96 end
= strrchr(entry
, '\n');
97 value
= strchr(entry
, '=');
98 if (end
== NULL
|| value
== NULL
|| entry
[i
] == '#')
105 * to be compatible with the old defread()-based code
106 * which ignored case, store the parameters (except for the
107 * leading interface name) in upper case.
110 if ((param
= strchr(entry
, '.')) == NULL
) {
111 pastv6
= param
= entry
;
114 if (strncasecmp(param
, "v6.", 3) == 0)
118 for (defp
= defaults
;
119 (char *)defp
< (char *)defaults
+ sizeof (defaults
);
121 if (strcasecmp(pastv6
, defp
->df_name
) == 0) {
122 if (defp
->df_max
== -1) {
123 dhcpmsg(MSG_WARNING
, "parameter %s is "
124 "obsolete; ignored", defp
->df_name
);
130 for (; *param
!= '\0'; param
++)
131 *param
= toupper(*param
);
133 if (nvlist_add_string(nvlist
, &entry
[i
], value
) != 0) {
134 dhcpmsg(MSG_WARNING
, "cannot build default value cache;"
135 " using built-in defaults");
147 * df_get_string(): gets the string value of a given user-tunable parameter
149 * input: const char *: the interface the parameter applies to
150 * boolean_t: B_TRUE for DHCPv6, B_FALSE for IPv4 DHCP
151 * uint_t: the parameter number to look up
152 * output: const char *: the parameter's value, or default if not set
153 * (must be copied by caller to be kept)
154 * NOTE: df_get_string() is both used by functions outside this source
155 * file to retrieve strings from the defaults file, *and*
156 * internally by other df_get_*() functions.
160 df_get_string(const char *if_name
, boolean_t isv6
, uint_t param
)
166 static struct stat df_statbuf
;
167 static boolean_t df_unavail_msg
= B_FALSE
;
168 static nvlist_t
*df_nvlist
= NULL
;
170 if (param
>= (sizeof (defaults
) / sizeof (*defaults
)))
173 if (stat(DHCP_AGENT_DEFAULTS
, &statbuf
) != 0) {
174 if (!df_unavail_msg
) {
175 dhcpmsg(MSG_WARNING
, "cannot access %s; using "
176 "built-in defaults", DHCP_AGENT_DEFAULTS
);
177 df_unavail_msg
= B_TRUE
;
179 return (defaults
[param
].df_default
);
183 * if our cached parameters are stale, rebuild.
186 if (statbuf
.st_mtime
!= df_statbuf
.st_mtime
||
187 statbuf
.st_size
!= df_statbuf
.st_size
) {
188 df_statbuf
= statbuf
;
189 nvlist_free(df_nvlist
);
190 df_nvlist
= df_build_cache();
194 (void) snprintf(name
, sizeof (name
), ".V6.%s",
195 defaults
[param
].df_name
);
196 (void) snprintf(paramstr
, sizeof (paramstr
), "%s%s", if_name
,
199 (void) strlcpy(name
, defaults
[param
].df_name
, sizeof (name
));
200 (void) snprintf(paramstr
, sizeof (paramstr
), "%s.%s", if_name
,
205 * first look for `if_name.[v6.]param', then `[v6.]param'. if neither
206 * has been set, use the built-in default.
209 if (nvlist_lookup_string(df_nvlist
, paramstr
, &value
) == 0 ||
210 nvlist_lookup_string(df_nvlist
, name
, &value
) == 0)
213 return (defaults
[param
].df_default
);
217 * df_get_int(): gets the integer value of a given user-tunable parameter
219 * input: const char *: the interface the parameter applies to
220 * boolean_t: B_TRUE for DHCPv6, B_FALSE for IPv4 DHCP
221 * uint_t: the parameter number to look up
222 * output: int: the parameter's value, or default if not set
226 df_get_int(const char *if_name
, boolean_t isv6
, uint_t param
)
231 if (param
>= (sizeof (defaults
) / sizeof (*defaults
)))
234 value
= df_get_string(if_name
, isv6
, param
);
235 if (value
== NULL
|| !isdigit(*value
))
238 value_int
= atoi(value
);
239 if (value_int
> defaults
[param
].df_max
||
240 value_int
< defaults
[param
].df_min
)
246 dhcpmsg(MSG_WARNING
, "df_get_int: parameter `%s' is not between %d and "
247 "%d, defaulting to `%s'", defaults
[param
].df_name
,
248 defaults
[param
].df_min
, defaults
[param
].df_max
,
249 defaults
[param
].df_default
);
250 return (atoi(defaults
[param
].df_default
));
254 * df_get_bool(): gets the boolean value of a given user-tunable parameter
256 * input: const char *: the interface the parameter applies to
257 * boolean_t: B_TRUE for DHCPv6, B_FALSE for IPv4 DHCP
258 * uint_t: the parameter number to look up
259 * output: boolean_t: B_TRUE if true, B_FALSE if false, default if not set
263 df_get_bool(const char *if_name
, boolean_t isv6
, uint_t param
)
267 if (param
>= (sizeof (defaults
) / sizeof (*defaults
)))
270 value
= df_get_string(if_name
, isv6
, param
);
273 if (strcasecmp(value
, "true") == 0 ||
274 strcasecmp(value
, "yes") == 0 || strcmp(value
, "1") == 0)
277 if (strcasecmp(value
, "false") == 0 ||
278 strcasecmp(value
, "no") == 0 || strcmp(value
, "0") == 0)
282 dhcpmsg(MSG_WARNING
, "df_get_bool: parameter `%s' has invalid value "
283 "`%s', defaulting to `%s'", defaults
[param
].df_name
,
284 value
!= NULL
? value
: "NULL", defaults
[param
].df_default
);
286 return ((atoi(defaults
[param
].df_default
) == 0) ? B_FALSE
: B_TRUE
);