xref: /illumos-gate/usr/src/cmd/tsol/tninfo/tninfo.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * tninfo.c - Trusted network reporting utility
31  */
32 #include <sys/types.h>
33 #include <errno.h>
34 #include <stdio.h>
35 #include <locale.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <libtsnet.h>
39 #include <netinet/in.h>
40 #include <arpa/inet.h>
41 #include <netdb.h>
42 #include <tsol/label.h>
43 #include <zone.h>
44 
45 /* maximum string size desired as returned by sb*tos calls */
46 #define	MAX_STRING_SIZE		60
47 
48 static void usage(void);
49 static int print_rhtp(const char *);
50 static int print_rh(const char *);
51 static int print_mlp(const char *);
52 
53 int
54 main(int argc, char *argv[])
55 {
56 	int chr;
57 	int ret = 0; /* return code */
58 
59 	/* set the locale for only the messages system (all else is clean) */
60 	(void) setlocale(LC_ALL, "");
61 #ifndef TEXT_DOMAIN		/* Should be defined by cc -D */
62 #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it weren't */
63 #endif
64 
65 	(void) textdomain(TEXT_DOMAIN);
66 
67 	if (argc <= 1)
68 		usage();
69 
70 	while ((chr = getopt(argc, argv, "h:m:t:")) != EOF) {
71 		switch (chr) {
72 		case 'h':
73 			ret |= print_rh(optarg);
74 			break;
75 		case 'm':
76 			ret |= print_mlp(optarg);
77 			break;
78 		case 't':
79 			ret |= print_rhtp(optarg);
80 			break;
81 		default:
82 			usage();
83 		}
84 	}
85 
86 	return (ret);
87 }
88 
89 static void
90 usage(void)
91 {
92 	(void) fprintf(stderr, gettext("usage: tninfo [-h host_name] "
93 	    "[-m zone_name] [-t template_name]\n"));
94 	exit(1);
95 }
96 
97 static int
98 print_rhtp(const char *rhtp_name)
99 {
100 	tsol_tpent_t tp;
101 	const char *str, *str2;
102 	const bslabel_t *l1, *l2;
103 	int i;
104 
105 	(void) strlcpy(tp.name, rhtp_name, sizeof (tp.name));
106 
107 	if (tnrhtp(TNDB_GET, &tp) != 0) {
108 		if (errno == ENOENT)
109 			(void) fprintf(stderr, gettext("tninfo: tnrhtp entry "
110 			    "%1$s does not exist\n"), tp.name);
111 		else
112 			(void) fprintf(stderr,
113 			    gettext("tninfo: tnrhtp TNDB_GET(%1$s) failed: "
114 			    "%2$s\n"), tp.name, strerror(errno));
115 		return (1);
116 	}
117 
118 	(void) printf("=====================================\n");
119 	(void) printf(gettext("Remote Host Template Table Entries:\n"));
120 
121 	(void) printf("__________________________\n");
122 	(void) printf(gettext("template: %s\n"), tp.name);
123 
124 	switch (tp.host_type) {
125 	case UNLABELED:
126 		(void) printf(gettext("host_type: UNLABELED\n"));
127 		(void) printf(gettext("doi: %d\n"), tp.tp_doi);
128 
129 		if (tp.tp_mask_unl & TSOL_MSK_DEF_LABEL) {
130 			str = sbsltos(&tp.tp_def_label, MAX_STRING_SIZE);
131 			if (str == NULL)
132 				str = gettext("translation failed");
133 			str2 = bsltoh(&tp.tp_def_label);
134 			if (str2 == NULL)
135 				str2 = gettext("translation failed");
136 			(void) printf(gettext("def_label: %s\nhex: %s\n"),
137 			    str, str2);
138 		}
139 
140 		if (tp.tp_mask_unl & TSOL_MSK_SL_RANGE_TSOL) {
141 			(void) printf(gettext("For routing only:\n"));
142 			str = sbsltos(&tp.tp_gw_sl_range.lower_bound,
143 			    MAX_STRING_SIZE);
144 			if (str == NULL)
145 				str = gettext("translation failed");
146 			str2 = bsltoh(&tp.tp_gw_sl_range.lower_bound);
147 			if (str2 == NULL)
148 				str2 = gettext("translation failed");
149 			(void) printf(gettext("min_sl: %s\nhex: %s\n"),
150 			    str, str2);
151 
152 			str = sbsltos(&tp.tp_gw_sl_range.upper_bound,
153 			    MAX_STRING_SIZE);
154 			if (str == NULL)
155 				str = gettext("translation failed");
156 			str2 = bsltoh(&tp.tp_gw_sl_range.upper_bound);
157 			if (str2 == NULL)
158 				str2 = gettext("translation failed");
159 			(void) printf(gettext("max_sl: %s\nhex: %s\n"),
160 			    str, str2);
161 
162 			l1 = (const blevel_t *)&tp.tp_gw_sl_set[0];
163 			l2 = (const blevel_t *)&tp.tp_gw_sl_set[NSLS_MAX];
164 			for (i = 0; l1 < l2; l1++, i++) {
165 				if (bisinvalid(l1))
166 					break;
167 				str = sbsltos(l1, MAX_STRING_SIZE);
168 				if (str == NULL)
169 					str = gettext("translation failed");
170 				if ((str2 = bsltoh(l1)) == NULL)
171 					str2 = gettext("translation failed");
172 				(void) printf(gettext("sl_set[%1$d]: %2$s\n"
173 				    "hex: %3$s\n"), i, str, str2);
174 			}
175 		}
176 		break;
177 
178 	case SUN_CIPSO:
179 		(void) printf(gettext("host_type: CIPSO\n"));
180 		(void) printf(gettext("doi: %d\n"), tp.tp_doi);
181 		if (tp.tp_mask_cipso & TSOL_MSK_SL_RANGE_TSOL) {
182 			str = sbsltos(&tp.tp_sl_range_cipso.lower_bound,
183 			    MAX_STRING_SIZE);
184 			if (str == NULL)
185 				str = gettext("translation failed");
186 			str2 = bsltoh(&tp.tp_sl_range_cipso.lower_bound);
187 			if (str2 == NULL)
188 				str2 = gettext("translation failed");
189 			(void) printf(gettext("min_sl: %s\nhex: %s\n"),
190 			    str, str2);
191 			str = sbsltos(&tp.tp_sl_range_cipso.upper_bound,
192 			    MAX_STRING_SIZE);
193 			if (str == NULL)
194 				str = gettext("translation failed");
195 			str2 = bsltoh(&tp.tp_sl_range_cipso.upper_bound);
196 			if (str2 == NULL)
197 				str2 = gettext("translation failed");
198 			(void) printf(gettext("max_sl: %s\nhex: %s\n"),
199 			    str, str2);
200 
201 			l1 = (const blevel_t *)&tp.tp_sl_set_cipso[0];
202 			l2 = (const blevel_t *)&tp.tp_sl_set_cipso[NSLS_MAX];
203 			for (i = 0; l1 < l2; l1++, i++) {
204 				if (bisinvalid(l1))
205 					break;
206 				str = sbsltos(l1, MAX_STRING_SIZE);
207 				if (str == NULL)
208 					str = gettext("translation failed");
209 				if ((str2 = bsltoh(l1)) == NULL)
210 					str2 = gettext("translation failed");
211 				(void) printf(gettext("sl_set[%1$d]: %2$s\n"
212 				    "hex: %3$s\n"), i, str, str2);
213 			}
214 		}
215 		break;
216 
217 	default:
218 		(void) printf(gettext("unsupported host type: %ld\n"),
219 		    tp.host_type);
220 	}
221 	return (0);
222 }
223 
224 static int
225 print_rh(const char *rh_name)
226 {
227 	int herr;
228 	struct hostent *hp;
229 	in6_addr_t in6;
230 	char abuf[INET6_ADDRSTRLEN];
231 	tsol_rhent_t rhent;
232 
233 	if ((hp = getipnodebyname(rh_name, AF_INET6,
234 	    AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED, &herr)) == NULL) {
235 		(void) fprintf(stderr, gettext("tninfo: unknown host or "
236 		    "invalid literal address: %s\n"), rh_name);
237 		if (herr == TRY_AGAIN)
238 			(void) fprintf(stderr,
239 			    gettext("\t(try again later)\n"));
240 		return (1);
241 	}
242 
243 	(void) memset(&rhent, 0, sizeof (rhent));
244 	(void) memcpy(&in6, hp->h_addr, hp->h_length);
245 
246 	if (IN6_IS_ADDR_V4MAPPED(&in6)) {
247 		rhent.rh_address.ta_family = AF_INET;
248 		IN6_V4MAPPED_TO_INADDR(&in6, &rhent.rh_address.ta_addr_v4);
249 		(void) inet_ntop(AF_INET, &rhent.rh_address.ta_addr_v4, abuf,
250 		    sizeof (abuf));
251 	} else {
252 		rhent.rh_address.ta_family = AF_INET6;
253 		rhent.rh_address.ta_addr_v6 = in6;
254 		(void) inet_ntop(AF_INET6, &in6, abuf, sizeof (abuf));
255 	}
256 
257 	(void) printf(gettext("IP address= %s\n"), abuf);
258 
259 	if (tnrh(TNDB_GET, &rhent) != 0) {
260 		if (errno == ENOENT)
261 			(void) fprintf(stderr, gettext("tninfo: tnrhdb entry "
262 			    "%1$s does not exist\n"), abuf);
263 		else
264 			(void) fprintf(stderr, gettext("tninfo: TNDB_GET(%1$s) "
265 			    "failed: %2$s\n"), abuf, strerror(errno));
266 		return (1);
267 	}
268 
269 	if (rhent.rh_template[0] != '\0')
270 		(void) printf(gettext("Template = %.*s\n"), TNTNAMSIZ,
271 		    rhent.rh_template);
272 	else
273 		(void) printf(gettext("No template exists.\n"));
274 
275 	return (0);
276 }
277 
278 static int
279 iterate_mlps(tsol_mlpent_t *tsme, const char *type)
280 {
281 	struct protoent *pe;
282 
283 	/* get the first entry */
284 	tsme->tsme_mlp.mlp_ipp = 0;
285 	tsme->tsme_mlp.mlp_port = 0;
286 	tsme->tsme_mlp.mlp_port_upper = 0;
287 	if (tnmlp(TNDB_GET, tsme) == -1) {
288 		if (errno == ENOENT) {
289 			(void) printf(gettext("%s: no entries\n"), type);
290 			return (0);
291 		} else {
292 			perror("tnmlp TNDB_GET");
293 			return (-1);
294 		}
295 	}
296 	(void) printf("%s: ", type);
297 	for (;;) {
298 		(void) printf("%u", tsme->tsme_mlp.mlp_port);
299 		if (tsme->tsme_mlp.mlp_port != tsme->tsme_mlp.mlp_port_upper)
300 			(void) printf("-%u", tsme->tsme_mlp.mlp_port_upper);
301 		if ((pe = getprotobynumber(tsme->tsme_mlp.mlp_ipp)) == NULL)
302 			(void) printf("/%u", tsme->tsme_mlp.mlp_ipp);
303 		else
304 			(void) printf("/%s", pe->p_name);
305 		if (tsme->tsme_mlp.mlp_ipp == 255) {
306 			tsme->tsme_mlp.mlp_port++;
307 			tsme->tsme_mlp.mlp_ipp = 0;
308 		} else {
309 			tsme->tsme_mlp.mlp_ipp++;
310 		}
311 		if (tnmlp(TNDB_GET, tsme) == -1)
312 			break;
313 		(void) putchar(';');
314 	}
315 	(void) putchar('\n');
316 	return (0);
317 }
318 
319 /*
320  * Print all of the MLPs for the given zone.
321  */
322 static int
323 print_mlp(const char *zonename)
324 {
325 	tsol_mlpent_t tsme;
326 
327 	if ((tsme.tsme_zoneid = getzoneidbyname(zonename)) == -1) {
328 		(void) fprintf(stderr, gettext("tninfo: zone '%s' unknown\n"),
329 		    zonename);
330 		return (1);
331 	}
332 	tsme.tsme_flags = 0;
333 	if (iterate_mlps(&tsme, gettext("private")) == -1)
334 		return (1);
335 	tsme.tsme_flags = TSOL_MEF_SHARED;
336 	if (iterate_mlps(&tsme, gettext("shared")) == -1)
337 		return (1);
338 	return (0);
339 }
340