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