4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 #include <sys/types.h>
32 #include <sys/openpromio.h>
35 #include <stdio.h> /* sprintf() */
39 * opp_zalloc(): allocates and initializes a struct openpromio
41 * input: size_t: the size of the variable-length part of the openpromio
42 * const char *: an initial value for oprom_array, if non-NULL
43 * output: struct openpromio: the allocated, initialized openpromio
46 static struct openpromio
*
47 opp_zalloc(size_t size
, const char *prop
)
49 struct openpromio
*opp
= malloc(sizeof (struct openpromio
) + size
);
52 (void) memset(opp
, 0, sizeof (struct openpromio
) + size
);
53 opp
->oprom_size
= size
;
55 (void) strcpy(opp
->oprom_array
, prop
);
61 * goto_rootnode(): moves to the root of the devinfo tree
63 * input: int: an open descriptor to /dev/openprom
64 * output: int: nonzero on success
68 goto_rootnode(int prom_fd
)
70 struct openpromio op
= { sizeof (int), 0 };
72 /* zero it explicitly since a union is involved */
74 return (ioctl(prom_fd
, OPROMNEXT
, &op
) == 0);
78 * return_property(): returns the value of a given property
80 * input: int: an open descriptor to /dev/openprom
81 * const char *: the property to look for in the current devinfo node
82 * output: the value of that property (dynamically allocated)
86 return_property(int prom_fd
, const char *prop
)
90 struct openpromio
*opp
= opp_zalloc(strlen(prop
) + 1, prop
);
95 if (ioctl(prom_fd
, OPROMGETPROPLEN
, opp
) == -1) {
100 proplen
= opp
->oprom_len
;
101 if (proplen
> (strlen(prop
) + 1)) {
103 opp
= opp_zalloc(proplen
, prop
);
108 if (ioctl(prom_fd
, OPROMGETPROP
, opp
) == -1) {
113 result
= strdup(opp
->oprom_array
);
119 * sanitize_class_id(): translates the class id into a canonical format,
120 * so that it can be used easily with dhcptab(4).
122 * input: char *: the class id to canonicalize
127 sanitize_class_id(char *src_ptr
)
129 char *dst_ptr
= src_ptr
;
131 /* remove all spaces and change all commas to periods */
132 while (*src_ptr
!= '\0') {
144 *dst_ptr
++ = *src_ptr
;
153 * get_class_id(): retrieves the class id from the prom, then canonicalizes it
156 * output: char *: the class id (dynamically allocated and sanitized)
163 char *name
, *class_id
= NULL
;
166 prom_fd
= open("/dev/openprom", O_RDONLY
);
170 if (goto_rootnode(prom_fd
) == 0) {
171 (void) close(prom_fd
);
176 * the `name' property is the same as the result of `uname -i', modulo
177 * some stylistic issues we fix up via sanitize_class_id() below.
180 name
= return_property(prom_fd
, "name");
181 (void) close(prom_fd
);
186 * if the name is not prefixed with a vendor name, add "SUNW," to make
187 * it more likely to be globally unique; see PSARC/2004/674.
190 if (strchr(name
, ',') == NULL
) {
191 len
= strlen(name
) + sizeof ("SUNW,");
192 class_id
= malloc(len
);
193 if (class_id
== NULL
) {
197 (void) snprintf(class_id
, len
, "SUNW,%s", name
);
203 sanitize_class_id(class_id
);