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 "misc.c 5.15 00/05/31 SMI; TSOL 2.x"
29 * Miscellaneous user interfaces to trusted label functions.
40 #include <tsol/label.h>
42 #include <net/route.h>
44 #define MAX_ATTR_LEN 1024
47 * Parse off an entry from a line. Entry is stored in 'outbuf'. Returned
48 * value is a pointer to the first unprocessed input character from 'instr'.
51 parse_entry(char *outbuf
, size_t outlen
, const char *instr
,
54 boolean_t escape_state
= B_FALSE
;
58 any_white
= strchr(delimit
, '\n') != NULL
;
61 * User may specify outlen as 0 to skip over a field without storing
62 * it anywhere. Otherwise, we need at least one byte for the
63 * terminating NUL plus one byte to store another byte from instr.
65 while (outlen
!= 1 && (chr
= *instr
++) != '\0') {
68 escape_state
= B_TRUE
;
71 if (strchr(delimit
, chr
) != NULL
)
73 if (any_white
&& isspace(chr
))
76 escape_state
= B_FALSE
;
92 sl_to_str(const m_label_t
*sl
)
95 static char unknown_str
[] = "UNKNOWN";
98 return (strdup(unknown_str
));
100 if ((label_to_str(sl
, &sl_str
, M_LABEL
, DEF_NAMES
) != 0) &&
101 (label_to_str(sl
, &sl_str
, M_INTERNAL
, DEF_NAMES
) != 0))
102 return (strdup(unknown_str
));
107 static const char *rtsa_keywords
[] = {
123 rtsa_to_str(const struct rtsa_s
*rtsa
, char *line
, size_t len
)
131 mask
= rtsa
->rtsa_mask
;
133 for (i
= 1; mask
!= 0 && i
!= 0 && slen
< len
- 1; i
<<= 1) {
134 if (!(i
& (RTSA_MINSL
|RTSA_MAXSL
|RTSA_DOI
|RTSA_CIPSO
)))
142 if ((mask
& RTSA_MAXSL
) &&
143 blequal(&rtsa
->rtsa_slrange
.lower_bound
,
144 &rtsa
->rtsa_slrange
.upper_bound
)) {
147 sl_to_str(&rtsa
->rtsa_slrange
.lower_bound
);
148 slen
+= snprintf(line
+ slen
, len
- slen
,
155 sl_str
= sl_to_str(&rtsa
->rtsa_slrange
.lower_bound
);
156 slen
+= snprintf(line
+ slen
, len
- slen
, "min_sl=%s",
162 sl_str
= sl_to_str(&rtsa
->rtsa_slrange
.upper_bound
);
163 slen
+= snprintf(line
+ slen
, len
- slen
, "max_sl=%s",
169 slen
+= snprintf(line
+ slen
, len
- slen
, "doi=%d",
173 slen
+= snprintf(line
+ slen
, len
- slen
, "cipso");
182 rtsa_keyword(const char *options
, struct rtsa_s
*sp
, int *errp
, char **errstrp
)
184 const char *valptr
, *nxtopt
;
185 uint32_t mask
= 0, doi
;
187 m_label_t
*min_sl
= NULL
, *max_sl
= NULL
;
188 char attrbuf
[MAX_ATTR_LEN
];
189 const char **keyword
;
198 *errstrp
= (char *)options
;
200 while (*options
!= '\0') {
201 valptr
= parse_entry(attrbuf
, sizeof (attrbuf
), options
, ",=");
203 if (attrbuf
[0] == '\0') {
204 *errstrp
= (char *)options
;
205 *errp
= LTSNET_ILL_ENTRY
;
208 for (keyword
= rtsa_keywords
; *keyword
!= NULL
; keyword
++)
209 if (strcmp(*keyword
, attrbuf
) == 0)
211 if ((key
= keyword
- rtsa_keywords
) == SAK_INVAL
) {
212 *errstrp
= (char *)options
;
213 *errp
= LTSNET_ILL_KEY
;
216 if ((key
== SAK_CIPSO
&& *valptr
== '=') ||
217 (key
!= SAK_CIPSO
&& *valptr
!= '=')) {
218 *errstrp
= (char *)valptr
;
219 *errp
= LTSNET_ILL_VALDELIM
;
224 if (*valptr
== '=') {
226 nxtopt
= parse_entry(attrbuf
, sizeof (attrbuf
),
228 if (*nxtopt
== '=') {
229 *errstrp
= (char *)nxtopt
;
230 *errp
= LTSNET_ILL_KEYDELIM
;
239 if (mask
& RTSA_MINSL
) {
240 *errstrp
= (char *)options
;
241 *errp
= LTSNET_DUP_KEY
;
244 m_label_free(min_sl
); /* in case of duplicate */
246 if (str_to_label(attrbuf
, &min_sl
, MAC_LABEL
,
247 L_NO_CORRECTION
, NULL
) != 0) {
248 *errstrp
= (char *)valptr
;
249 *errp
= LTSNET_ILL_LOWERBOUND
;
256 if (mask
& RTSA_MAXSL
) {
257 *errstrp
= (char *)options
;
258 *errp
= LTSNET_DUP_KEY
;
261 m_label_free(max_sl
); /* in case of duplicate */
263 if (str_to_label(attrbuf
, &max_sl
, MAC_LABEL
,
264 L_NO_CORRECTION
, NULL
) != 0) {
265 *errstrp
= (char *)valptr
;
266 *errp
= LTSNET_ILL_UPPERBOUND
;
273 if (mask
& (RTSA_MAXSL
|RTSA_MINSL
)) {
274 *errstrp
= (char *)options
;
275 *errp
= LTSNET_DUP_KEY
;
278 m_label_free(min_sl
); /* in case of duplicate */
280 if (str_to_label(attrbuf
, &min_sl
, MAC_LABEL
,
281 L_NO_CORRECTION
, NULL
) != 0) {
282 *errstrp
= (char *)valptr
;
283 *errp
= LTSNET_ILL_LABEL
;
287 mask
|= (RTSA_MINSL
| RTSA_MAXSL
);
291 if (mask
& RTSA_DOI
) {
292 *errstrp
= (char *)options
;
293 *errp
= LTSNET_DUP_KEY
;
297 doi
= strtoul(attrbuf
, &cp
, 0);
298 if (doi
== 0 || errno
!= 0 || *cp
!= '\0') {
299 *errstrp
= (char *)valptr
;
300 *errp
= LTSNET_ILL_DOI
;
307 if (mask
& RTSA_CIPSO
) {
308 *errstrp
= (char *)options
;
309 *errp
= LTSNET_DUP_KEY
;
319 /* Defaults to CIPSO if not specified */
322 /* If RTSA_CIPSO is specified, RTSA_DOI must be specified */
323 if (!(mask
& RTSA_DOI
)) {
324 *errp
= LTSNET_NO_DOI
;
328 /* SL range must be specified */
329 if (!(mask
& (RTSA_MINSL
|RTSA_MAXSL
))) {
330 *errp
= LTSNET_NO_RANGE
;
333 if (!(mask
& RTSA_MINSL
)) {
334 *errp
= LTSNET_NO_LOWERBOUND
;
337 if (!(mask
& RTSA_MAXSL
)) {
338 *errp
= LTSNET_NO_UPPERBOUND
;
342 /* SL range must have upper bound dominating lower bound */
343 if (!bldominates(max_sl
, min_sl
)) {
344 *errp
= LTSNET_ILL_RANGE
;
348 if (mask
& RTSA_MINSL
)
349 sp
->rtsa_slrange
.lower_bound
= *min_sl
;
350 if (mask
& RTSA_MAXSL
)
351 sp
->rtsa_slrange
.upper_bound
= *max_sl
;
354 sp
->rtsa_mask
= mask
;
356 m_label_free(min_sl
);
357 m_label_free(max_sl
);
362 m_label_free(min_sl
);
363 m_label_free(max_sl
);
368 /* Keep in sync with libtsnet.h */
369 static const char *tsol_errlist
[] = {
372 "Empty string or end of list",
373 "Entry is malformed",
375 "Missing attributes",
377 "Illegal keyword delimiter",
380 "Illegal value delimiter",
385 "Missing label range",
386 "Illegal label range",
387 "No lower bound in range",
388 "Illegal lower bound in range",
389 "No upper bound in range",
390 "Illegal upper bound in range",
393 "Too many entries in set",
394 "Missing address/network",
395 "Illegal address/network",
397 "Illegal MLP specification",
398 "Unacceptable keyword for type"
400 static const int tsol_nerr
= sizeof (tsol_errlist
) / sizeof (*tsol_errlist
);
403 tsol_strerror(int libtserr
, int errnoval
)
405 if (libtserr
== LTSNET_SYSERR
)
406 return (strerror(errnoval
));
407 if (libtserr
>= 0 && libtserr
< tsol_nerr
)
408 return (gettext(tsol_errlist
[libtserr
]));
409 return (gettext("Unknown error"));