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