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