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 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
25 * From "tsol_tndb_parser.c 7.24 01/09/05 SMI; TSOL 2.x"
27 * These functions parse entries in the "tnzonecfg" (zone configuration) file.
28 * Each entry in this file has five fields, separated by a colon. These fields
31 * zone name : label : flags : zone-specific MLPs : global MLPs
33 * The fourth and fifth fields contain subfields consisting of MLP entries
34 * separated by semicolons. The MLP entries are of the form:
36 * port[-port]/protocol
38 * In order to help preserve sanity, we do not allow more than four unescaped
39 * colons in a line, nor any unescaped ';' characters in the non-MLP fields.
40 * Such things are indicative of typing errors, not intentional configuration.
49 #include <tsol/label.h>
50 #include <sys/types.h>
51 #include <sys/socket.h>
52 #include <netinet/in.h>
58 * Parse an MLP specification in port1-port2/proto or port/proto form.
61 str_to_mlp(char *mlp_str
, tsol_mlp_t
*zone_mlp
)
67 struct protoent proto
;
70 (void) memset(zone_mlp
, 0, sizeof (tsol_mlp_t
));
72 fieldp
= strtok_r(mlp_str
, KV_DELIMITER
, &lasts
);
77 for (i
= 0; fieldp
!= NULL
&& i
< NMLP_MAX
; i
++) {
78 ulv
= strtoul(fieldp
, &cp
, 0);
79 zone_mlp
[i
].mlp_port
= (uint16_t)ulv
;
80 zone_mlp
[i
].mlp_port_upper
= 0;
81 if (errno
!= 0 || ulv
> 65535)
84 ulv
= strtol(cp
+ 1, &cp
, 0);
85 zone_mlp
[i
].mlp_port_upper
= (uint16_t)ulv
;
86 if (errno
!= 0 || ulv
> 65535)
92 ulv
= strtol(fieldp
, &cp
, 0);
93 if (errno
== 0 && ulv
<= 255 && *cp
== '\0')
94 zone_mlp
->mlp_ipp
= (uint8_t)ulv
;
95 else if (getprotobyname_r(fieldp
, &proto
, gbuf
,
96 sizeof (gbuf
)) != NULL
)
97 zone_mlp
->mlp_ipp
= proto
.p_proto
;
100 fieldp
= strtok_r(NULL
, KV_DELIMITER
, &lasts
);
106 parse_mlp_list(tsol_mlp_t
**list
, char *str
, int *errp
, char **errstrp
)
110 char *tokp
, *finally
;
114 if ((mlp
= *list
) != NULL
) {
115 while (!TSOL_MLP_END(mlp
)) {
122 tokp
= strtok_r(str
, KV_DELIMITER
, &finally
);
123 for (mc
= 0; tokp
!= NULL
; mc
++) {
126 mlp
= realloc(mlp
, mmax
* sizeof (*mlp
));
128 *errp
= LTSNET_SYSERR
;
134 if (str_to_mlp(tokp
, mlp
+ mc
) == -1) {
135 *errp
= LTSNET_ILL_MLP
;
139 tokp
= strtok_r(NULL
, KV_DELIMITER
, &finally
);
142 mlp
= realloc(mlp
, (mmax
+ 1) * sizeof (*mlp
));
144 *errp
= LTSNET_SYSERR
;
150 (void) memset(mlp
+ mc
, 0, sizeof (*mlp
));
155 tsol_sgetzcent(const char *instr
, int *errp
, char **errstrp
)
166 * The user can specify NULL pointers for these. Make sure that we
167 * don't have to deal with checking for NULL everywhere by just
168 * pointing to our own variables if the user gives NULL.
175 /* The default, unless we find a more specific error locus. */
176 *errstrp
= (char *)instr
;
178 if ((zc
= calloc(1, sizeof (*zc
))) == NULL
) {
179 *errp
= LTSNET_SYSERR
;
183 /* First, parse off the zone name. */
184 instr
= parse_entry(zc
->zc_name
, sizeof (zc
->zc_name
), instr
, "#;:\n");
185 if (zc
->zc_name
[0] == '\0') {
186 *errstrp
= (char *)instr
;
187 if (*instr
== '\0' || *instr
== '#' || *instr
== '\n')
188 *errp
= LTSNET_EMPTY
;
189 else if (*instr
== ':')
190 *errp
= LTSNET_NO_NAME
;
192 *errp
= LTSNET_ILL_NAME
;
196 *errstrp
= (char *)instr
;
197 if (*instr
== '=' || *instr
== ';')
198 *errp
= LTSNET_ILL_NAME
;
200 *errp
= LTSNET_ILL_ENTRY
;
205 /* Field two: parse off the label. */
206 nextf
= parse_entry(fieldbuf
, sizeof (fieldbuf
), instr
, "#;:\n");
208 *errstrp
= (char *)nextf
;
209 *errp
= LTSNET_ILL_ENTRY
;
212 if (fieldbuf
[0] == '\0') {
213 *errstrp
= (char *)instr
;
214 *errp
= LTSNET_NO_LABEL
;
219 if (str_to_label(fieldbuf
, &slp
, MAC_LABEL
, L_NO_CORRECTION
, NULL
)
221 *errstrp
= (char *)instr
;
222 *errp
= LTSNET_ILL_LABEL
;
227 /* The kernel will apply the system doi to the zone label later */
230 /* Field three: get match flag */
232 zc
->zc_match
= (uchar_t
)strtol(instr
, &cp
, 0);
233 if (errno
!= 0 || (*cp
!= ':' && *cp
!= '\0')) {
234 *errp
= LTSNET_ILL_FLAG
;
235 *errstrp
= (char *)instr
;
239 *errp
= LTSNET_ILL_VALDELIM
;
245 /* Field four: get zone-specific MLP list. */
246 nextf
= parse_entry(fieldbuf
, sizeof (fieldbuf
), instr
, "#:\n");
248 *errstrp
= (char *)nextf
;
249 *errp
= LTSNET_ILL_ENTRY
;
252 if (!parse_mlp_list(&zc
->zc_private_mlp
, fieldbuf
, errp
, errstrp
)) {
253 *errstrp
= (char *)instr
+ (*errstrp
- fieldbuf
);
258 /* Field five: get global MLP list. */
259 nextf
= parse_entry(fieldbuf
, sizeof (fieldbuf
), instr
, "#:\n");
260 if (*nextf
!= '\0' && *nextf
!= '#' && !isspace(*nextf
)) {
261 *errstrp
= (char *)nextf
;
262 *errp
= LTSNET_ILL_ENTRY
;
265 if (!parse_mlp_list(&zc
->zc_shared_mlp
, fieldbuf
, errp
, errstrp
)) {
266 *errstrp
= (char *)instr
+ (*errstrp
- fieldbuf
);
280 tsol_freezcent(tsol_zcent_t
*zc
)
283 free(zc
->zc_private_mlp
);
284 free(zc
->zc_shared_mlp
);