Print this page
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.c
+++ new/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #include <sys/types.h>
27 27 #include <stdlib.h>
28 28 #include <string.h>
29 29 #include <ctype.h>
30 30 #include <dhcpmsg.h>
31 31 #include <stdio.h>
32 32 #include <sys/stat.h>
33 33 #include <libnvpair.h>
34 34 #include <zone.h>
35 35
36 36 #include "common.h"
37 37 #include "defaults.h"
38 38
39 39 struct dhcp_default {
40 40
41 41 const char *df_name; /* parameter name */
42 42 const char *df_default; /* default value */
43 43 int df_min; /* min value if type DF_INTEGER */
44 44 int df_max; /* max value if type DF_INTEGER */
45 45 };
46 46
47 47 /*
48 48 * note: keep in the same order as tunable parameter constants in defaults.h
49 49 */
50 50
51 51 static struct dhcp_default defaults[] = {
52 52
53 53 { "RELEASE_ON_SIGTERM", "0", 0, 0 },
54 54 { "IGNORE_FAILED_ARP", "1", 0, -1 },
55 55 { "OFFER_WAIT", "3", 1, 20 },
56 56 { "ARP_WAIT", "1000", 0, -1 },
57 57 { "CLIENT_ID", NULL, 0, 0 },
58 58 { "PARAM_REQUEST_LIST", NULL, 0, 0 },
59 59 { "REQUEST_HOSTNAME", "1", 0, 0 },
60 60 { "DEBUG_LEVEL", "0", 0, 3 },
61 61 { "VERBOSE", "0", 0, 0 },
62 62 { "VERIFIED_LEASE_ONLY", "0", 0, 0 },
63 63 { "PARAM_IGNORE_LIST", NULL, 0, 0 }
64 64 };
65 65
66 66
67 67 /*
68 68 * df_find_defaults(): builds the path to the default configuration file
69 69 *
70 70 * input: void
71 71 * output: void
72 72 */
73 73
74 74 static const char *
75 75 df_find_defaults(void)
76 76 {
77 77 static char agent_defaults_path[MAXPATHLEN] = { 0 };
78 78 const char *zroot = NULL;
79 79
80 80 if (agent_defaults_path[0] != '\0') {
81 81 return agent_defaults_path;
82 82 }
83 83
84 84 zroot = zone_get_nroot();
85 85
86 86 (void) snprintf(agent_defaults_path, MAXPATHLEN, "%s%s",
87 87 zroot != NULL ? zroot : "", DHCP_AGENT_DEFAULTS);
88 88
89 89 return agent_defaults_path;
90 90 }
91 91
92 92 /*
93 93 * df_build_cache(): builds the defaults nvlist cache
94 94 *
95 95 * input: void
96 96 * output: a pointer to an nvlist of the current defaults, or NULL on failure
97 97 */
98 98
99 99 static nvlist_t *
100 100 df_build_cache(void)
101 101 {
102 102 const char *agent_defaults_path = df_find_defaults();
103 103 char entry[1024];
104 104 int i;
105 105 char *param, *pastv6, *value, *end;
106 106 FILE *fp;
107 107 nvlist_t *nvlist;
108 108 struct dhcp_default *defp;
109 109
110 110 if ((fp = fopen(agent_defaults_path, "r")) == NULL)
111 111 return (NULL);
112 112
113 113 if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) {
114 114 dhcpmsg(MSG_WARNING, "cannot build default value cache; "
115 115 "using built-in defaults");
116 116 (void) fclose(fp);
117 117 return (NULL);
118 118 }
119 119
120 120 while (fgets(entry, sizeof (entry), fp) != NULL) {
121 121 for (i = 0; entry[i] == ' '; i++)
122 122 ;
123 123
124 124 end = strrchr(entry, '\n');
125 125 value = strchr(entry, '=');
126 126 if (end == NULL || value == NULL || entry[i] == '#')
127 127 continue;
128 128
129 129 *end = '\0';
130 130 *value++ = '\0';
131 131
132 132 /*
133 133 * to be compatible with the old defread()-based code
134 134 * which ignored case, store the parameters (except for the
135 135 * leading interface name) in upper case.
136 136 */
137 137
138 138 if ((param = strchr(entry, '.')) == NULL) {
139 139 pastv6 = param = entry;
140 140 } else {
141 141 pastv6 = ++param;
142 142 if (strncasecmp(param, "v6.", 3) == 0)
143 143 pastv6 += 3;
144 144 }
145 145
146 146 for (defp = defaults;
147 147 (char *)defp < (char *)defaults + sizeof (defaults);
148 148 defp++) {
149 149 if (strcasecmp(pastv6, defp->df_name) == 0) {
150 150 if (defp->df_max == -1) {
151 151 dhcpmsg(MSG_WARNING, "parameter %s is "
152 152 "obsolete; ignored", defp->df_name);
153 153 }
154 154 break;
155 155 }
156 156 }
157 157
158 158 for (; *param != '\0'; param++)
159 159 *param = toupper(*param);
160 160
161 161 if (nvlist_add_string(nvlist, &entry[i], value) != 0) {
162 162 dhcpmsg(MSG_WARNING, "cannot build default value cache;"
163 163 " using built-in defaults");
164 164 nvlist_free(nvlist);
165 165 nvlist = NULL;
166 166 break;
167 167 }
168 168 }
169 169
170 170 (void) fclose(fp);
171 171 return (nvlist);
172 172 }
173 173
174 174 /*
175 175 * df_get_string(): gets the string value of a given user-tunable parameter
176 176 *
177 177 * input: const char *: the interface the parameter applies to
178 178 * boolean_t: B_TRUE for DHCPv6, B_FALSE for IPv4 DHCP
179 179 * uint_t: the parameter number to look up
180 180 * output: const char *: the parameter's value, or default if not set
181 181 * (must be copied by caller to be kept)
182 182 * NOTE: df_get_string() is both used by functions outside this source
183 183 * file to retrieve strings from the defaults file, *and*
184 184 * internally by other df_get_*() functions.
185 185 */
186 186
187 187 const char *
188 188 df_get_string(const char *if_name, boolean_t isv6, uint_t param)
189 189 {
190 190 const char *agent_defaults_path = df_find_defaults();
191 191 char *value;
192 192 char paramstr[256];
193 193 char name[256];
194 194 struct stat statbuf;
195 195 static struct stat df_statbuf;
196 196 static boolean_t df_unavail_msg = B_FALSE;
197 197 static nvlist_t *df_nvlist = NULL;
198 198
199 199 if (param >= (sizeof (defaults) / sizeof (*defaults)))
200 200 return (NULL);
201 201
202 202
203 203 if (stat(agent_defaults_path, &statbuf) != 0) {
204 204 if (!df_unavail_msg) {
205 205 dhcpmsg(MSG_WARNING, "cannot access %s; using "
206 206 "built-in defaults", agent_defaults_path);
207 207 df_unavail_msg = B_TRUE;
208 208 }
209 209 return (defaults[param].df_default);
210 210 }
211 211
212 212 /*
213 213 * if our cached parameters are stale, rebuild.
214 214 */
215 215
216 216 if (statbuf.st_mtime != df_statbuf.st_mtime ||
217 217 statbuf.st_size != df_statbuf.st_size) {
218 218 df_statbuf = statbuf;
219 219 nvlist_free(df_nvlist);
220 220 df_nvlist = df_build_cache();
221 221 }
222 222
223 223 if (isv6) {
224 224 (void) snprintf(name, sizeof (name), ".V6.%s",
225 225 defaults[param].df_name);
226 226 (void) snprintf(paramstr, sizeof (paramstr), "%s%s", if_name,
227 227 name);
228 228 } else {
229 229 (void) strlcpy(name, defaults[param].df_name, sizeof (name));
230 230 (void) snprintf(paramstr, sizeof (paramstr), "%s.%s", if_name,
231 231 name);
232 232 }
233 233
234 234 /*
235 235 * first look for `if_name.[v6.]param', then `[v6.]param'. if neither
236 236 * has been set, use the built-in default.
237 237 */
238 238
239 239 if (nvlist_lookup_string(df_nvlist, paramstr, &value) == 0 ||
240 240 nvlist_lookup_string(df_nvlist, name, &value) == 0)
241 241 return (value);
242 242
243 243 return (defaults[param].df_default);
244 244 }
245 245
246 246 /*
247 247 * df_get_int(): gets the integer value of a given user-tunable parameter
248 248 *
249 249 * input: const char *: the interface the parameter applies to
250 250 * boolean_t: B_TRUE for DHCPv6, B_FALSE for IPv4 DHCP
251 251 * uint_t: the parameter number to look up
252 252 * output: int: the parameter's value, or default if not set
253 253 */
254 254
255 255 int
256 256 df_get_int(const char *if_name, boolean_t isv6, uint_t param)
257 257 {
258 258 const char *value;
259 259 int value_int;
260 260
261 261 if (param >= (sizeof (defaults) / sizeof (*defaults)))
262 262 return (0);
263 263
264 264 value = df_get_string(if_name, isv6, param);
265 265 if (value == NULL || !isdigit(*value))
266 266 goto failure;
267 267
268 268 value_int = atoi(value);
269 269 if (value_int > defaults[param].df_max ||
270 270 value_int < defaults[param].df_min)
271 271 goto failure;
272 272
273 273 return (value_int);
274 274
275 275 failure:
276 276 dhcpmsg(MSG_WARNING, "df_get_int: parameter `%s' is not between %d and "
277 277 "%d, defaulting to `%s'", defaults[param].df_name,
278 278 defaults[param].df_min, defaults[param].df_max,
279 279 defaults[param].df_default);
280 280 return (atoi(defaults[param].df_default));
281 281 }
282 282
283 283 /*
284 284 * df_get_bool(): gets the boolean value of a given user-tunable parameter
285 285 *
286 286 * input: const char *: the interface the parameter applies to
287 287 * boolean_t: B_TRUE for DHCPv6, B_FALSE for IPv4 DHCP
288 288 * uint_t: the parameter number to look up
289 289 * output: boolean_t: B_TRUE if true, B_FALSE if false, default if not set
290 290 */
291 291
292 292 boolean_t
293 293 df_get_bool(const char *if_name, boolean_t isv6, uint_t param)
294 294 {
295 295 const char *value;
296 296
297 297 if (param >= (sizeof (defaults) / sizeof (*defaults)))
298 298 return (0);
299 299
300 300 value = df_get_string(if_name, isv6, param);
301 301 if (value != NULL) {
302 302
303 303 if (strcasecmp(value, "true") == 0 ||
304 304 strcasecmp(value, "yes") == 0 || strcmp(value, "1") == 0)
305 305 return (B_TRUE);
306 306
307 307 if (strcasecmp(value, "false") == 0 ||
308 308 strcasecmp(value, "no") == 0 || strcmp(value, "0") == 0)
309 309 return (B_FALSE);
310 310 }
311 311
312 312 dhcpmsg(MSG_WARNING, "df_get_bool: parameter `%s' has invalid value "
313 313 "`%s', defaulting to `%s'", defaults[param].df_name,
314 314 value != NULL ? value : "NULL", defaults[param].df_default);
315 315
316 316 return ((atoi(defaults[param].df_default) == 0) ? B_FALSE : B_TRUE);
317 317 }
|
↓ open down ↓ |
317 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX