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